From c2f39c3bbc43c4483dada82297b9ffbdaddc157e Mon Sep 17 00:00:00 2001 From: arm64v8a <48624112+arm64v8a@users.noreply.github.com> Date: Sat, 18 Mar 2023 13:21:51 +0900 Subject: [PATCH] update ui --- app/.gitignore | 1 - app/build.gradle.kts | 31 +- .../1.json | 330 +++++++++++++++++ .../2.json | 342 ++++++++++++++++++ .../1.json | 46 +++ .../moe.matsuri.nb4a.TempDatabase/1.json | 46 +++ .../java/io/nekohasekai/sagernet/Constants.kt | 1 + .../sagernet/bg/SagerConnection.kt | 5 +- .../sagernet/bg/proto/BoxInstance.kt | 2 +- .../sagernet/database/DataStore.kt | 1 + .../sagernet/database/ProfileManager.kt | 1 - .../sagernet/database/ProxyEntity.kt | 6 +- .../sagernet/database/ProxyGroup.kt | 2 + .../sagernet/database/SagerDatabase.kt | 2 +- .../nekohasekai/sagernet/fmt/ConfigBuilder.kt | 4 +- .../sagernet/fmt/KryoConverters.java | 2 +- .../sagernet/fmt/hysteria/HysteriaFmt.kt | 1 - .../fmt/shadowsocks/ShadowsocksFmt.kt | 2 +- .../sagernet/fmt/socks/SOCKSFmt.kt | 5 +- .../sagernet/fmt/trojan/TrojanBean.java | 1 - .../sagernet/fmt/v2ray/V2RayFmt.kt | 2 +- .../io/nekohasekai/sagernet/ktx/Formats.kt | 2 +- .../io/nekohasekai/sagernet/ktx/Layouts.kt | 1 - .../sagernet/ui/AppListActivity.kt | 2 +- .../sagernet/ui/ConfigurationFragment.kt | 10 +- .../sagernet/ui/GroupSettingsActivity.kt | 49 ++- .../nekohasekai/sagernet/ui/MainActivity.kt | 1 - .../sagernet/ui/RouteSettingsActivity.kt | 4 +- .../sagernet/ui/SettingsPreferenceFragment.kt | 11 +- .../ui/profile/ChainSettingsActivity.kt | 2 +- .../ui/profile/HysteriaSettingsActivity.kt | 4 +- .../ui/profile/NaiveSettingsActivity.kt | 2 +- .../ui/profile/ProfileSettingsActivity.kt | 4 +- .../ui/profile/SSHSettingsActivity.kt | 4 +- .../ui/profile/ShadowsocksSettingsActivity.kt | 2 +- .../ui/profile/SocksSettingsActivity.kt | 5 +- .../profile/StandardV2RaySettingsActivity.kt | 5 +- .../ui/profile/TrojanGoSettingsActivity.kt | 4 +- .../ui/profile/TuicSettingsActivity.kt | 4 +- .../ui/profile/WireGuardSettingsActivity.kt | 2 +- .../sagernet/widget/GroupPreference.kt | 18 +- .../widget/LinkOrContentPreference.kt | 26 +- .../sagernet/widget/LinkPreference.kt | 52 +-- .../sagernet/widget/OutboundPreference.kt | 22 +- .../sagernet/widget/UserAgentPreference.kt | 19 +- .../java/moe/matsuri/nb4a/plugin/Plugins.kt | 1 - .../matsuri/nb4a/proxy/PreferenceBinding.kt | 4 +- .../nb4a/proxy/PreferenceBindingManager.kt | 3 +- .../proxy/config/ConfigSettingActivity.kt | 4 +- .../nb4a/proxy/neko/NekoJSInterface.kt | 2 +- .../nb4a/proxy/neko/NekoPreferenceInflater.kt | 35 +- .../nb4a/proxy/neko/NekoSettingActivity.kt | 2 +- .../nb4a/ui/LongClickMenuPreference.kt | 10 +- .../java/moe/matsuri/nb4a/ui/MTUPreference.kt | 18 +- .../matsuri/nb4a/ui/SimpleMenuPreference.kt | 86 +++++ .../main/java/moe/matsuri/nb4a/utils/Util.kt | 6 - app/src/main/res/layout/layout_backup.xml | 1 - .../res/layout/layout_icon_list_item_2.xml | 14 +- app/src/main/res/layout/layout_import.xml | 1 - .../res/layout/simple_menu_dropdown_item.xml | 25 ++ app/src/main/res/menu/app_list_neko_menu.xml | 3 +- app/src/main/res/menu/traffic_menu.xml | 3 +- app/src/main/res/values-night/colors.xml | 1 + app/src/main/res/values/colors.xml | 11 +- app/src/main/res/values/dimens.xml | 2 +- app/src/main/res/values/strings.xml | 2 + app/src/main/res/values/themes.xml | 2 +- app/src/main/res/xml/balancer_preferences.xml | 4 +- app/src/main/res/xml/config_preferences.xml | 3 +- app/src/main/res/xml/global_preferences.xml | 16 +- app/src/main/res/xml/group_preferences.xml | 19 +- app/src/main/res/xml/hysteria_preferences.xml | 4 +- app/src/main/res/xml/naive_preferences.xml | 2 +- app/src/main/res/xml/neko_preferences.xml | 3 +- app/src/main/res/xml/route_preferences.xml | 2 +- .../main/res/xml/shadowsocks_preferences.xml | 4 +- app/src/main/res/xml/socks_preferences.xml | 2 +- app/src/main/res/xml/ssh_preferences.xml | 2 +- .../res/xml/standard_v2ray_preferences.xml | 10 +- .../main/res/xml/trojan_go_preferences.xml | 6 +- app/src/main/res/xml/tuic_preferences.xml | 4 +- buildScript/init/action/gradle.sh | 2 + buildSrc/src/main/kotlin/Helpers.kt | 4 +- settings.gradle.kts | 3 - 84 files changed, 1125 insertions(+), 289 deletions(-) create mode 100644 app/schemas/io.nekohasekai.sagernet.database.SagerDatabase/1.json create mode 100644 app/schemas/io.nekohasekai.sagernet.database.SagerDatabase/2.json create mode 100644 app/schemas/io.nekohasekai.sagernet.database.preference.PublicDatabase/1.json create mode 100644 app/schemas/moe.matsuri.nb4a.TempDatabase/1.json create mode 100644 app/src/main/java/moe/matsuri/nb4a/ui/SimpleMenuPreference.kt create mode 100644 app/src/main/res/layout/simple_menu_dropdown_item.xml diff --git a/app/.gitignore b/app/.gitignore index 3f2a4d9..796b96d 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1,2 +1 @@ /build -/schemas diff --git a/app/build.gradle.kts b/app/build.gradle.kts index daee17b..5f3bc8b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -31,24 +31,21 @@ dependencies { implementation(fileTree("libs")) implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.3") - implementation("androidx.core:core-ktx:1.7.0") - implementation("androidx.recyclerview:recyclerview:1.2.1") - implementation("androidx.activity:activity-ktx:1.4.0") - implementation("androidx.fragment:fragment-ktx:1.4.1") - implementation("androidx.browser:browser:1.4.0") + implementation("androidx.core:core-ktx:1.9.0") + implementation("androidx.recyclerview:recyclerview:1.3.0") + implementation("androidx.activity:activity-ktx:1.6.1") + implementation("androidx.fragment:fragment-ktx:1.5.5") + implementation("androidx.browser:browser:1.5.0") implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0") implementation("androidx.constraintlayout:constraintlayout:2.1.4") - implementation("androidx.navigation:navigation-fragment-ktx:2.4.2") - implementation("androidx.navigation:navigation-ui-ktx:2.4.2") + implementation("androidx.navigation:navigation-fragment-ktx:2.5.3") + implementation("androidx.navigation:navigation-ui-ktx:2.5.3") implementation("androidx.preference:preference-ktx:1.2.0") - implementation("androidx.appcompat:appcompat:1.4.1") - implementation("androidx.work:work-runtime-ktx:2.7.1") - implementation("androidx.work:work-multiprocess:2.7.1") + implementation("androidx.appcompat:appcompat:1.6.1") + implementation("androidx.work:work-runtime-ktx:2.8.0") + implementation("androidx.work:work-multiprocess:2.8.0") - implementation(project(":external:preferencex:preferencex")) - implementation(project(":external:preferencex:preferencex-simplemenu")) - - implementation("com.google.android.material:material:1.6.0") + implementation("com.google.android.material:material:1.8.0") implementation("com.google.code.gson:gson:2.8.9") implementation("com.github.jenly1314:zxing-lite:2.1.1") @@ -71,9 +68,9 @@ dependencies { exclude(group = "com.google.guava", module = "guava") } - implementation("androidx.room:room-runtime:2.4.2") - kapt("androidx.room:room-compiler:2.4.2") - implementation("androidx.room:room-ktx:2.4.2") + implementation("androidx.room:room-runtime:2.5.0") + kapt("androidx.room:room-compiler:2.5.0") + implementation("androidx.room:room-ktx:2.5.0") implementation("com.github.MatrixDev.Roomigrant:RoomigrantLib:0.3.4") kapt("com.github.MatrixDev.Roomigrant:RoomigrantCompiler:0.3.4") diff --git a/app/schemas/io.nekohasekai.sagernet.database.SagerDatabase/1.json b/app/schemas/io.nekohasekai.sagernet.database.SagerDatabase/1.json new file mode 100644 index 0000000..5e9db91 --- /dev/null +++ b/app/schemas/io.nekohasekai.sagernet.database.SagerDatabase/1.json @@ -0,0 +1,330 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "f66fd943df1d9e86d281a2e32c9fdd47", + "entities": [ + { + "tableName": "proxy_groups", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `userOrder` INTEGER NOT NULL, `ungrouped` INTEGER NOT NULL, `name` TEXT, `type` INTEGER NOT NULL, `subscription` BLOB, `order` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userOrder", + "columnName": "userOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ungrouped", + "columnName": "ungrouped", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subscription", + "columnName": "subscription", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "proxy_entities", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `groupId` INTEGER NOT NULL, `type` INTEGER NOT NULL, `userOrder` INTEGER NOT NULL, `tx` INTEGER NOT NULL, `rx` INTEGER NOT NULL, `status` INTEGER NOT NULL, `ping` INTEGER NOT NULL, `uuid` TEXT NOT NULL, `error` TEXT, `socksBean` BLOB, `httpBean` BLOB, `ssBean` BLOB, `vmessBean` BLOB, `trojanBean` BLOB, `trojanGoBean` BLOB, `naiveBean` BLOB, `hysteriaBean` BLOB, `tuicBean` BLOB, `sshBean` BLOB, `wgBean` BLOB, `chainBean` BLOB, `nekoBean` BLOB, `configBean` BLOB)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "groupId", + "columnName": "groupId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userOrder", + "columnName": "userOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "tx", + "columnName": "tx", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "rx", + "columnName": "rx", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ping", + "columnName": "ping", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "uuid", + "columnName": "uuid", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "error", + "columnName": "error", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "socksBean", + "columnName": "socksBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "httpBean", + "columnName": "httpBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "ssBean", + "columnName": "ssBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "vmessBean", + "columnName": "vmessBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "trojanBean", + "columnName": "trojanBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "trojanGoBean", + "columnName": "trojanGoBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "naiveBean", + "columnName": "naiveBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "hysteriaBean", + "columnName": "hysteriaBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "tuicBean", + "columnName": "tuicBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "sshBean", + "columnName": "sshBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "wgBean", + "columnName": "wgBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "chainBean", + "columnName": "chainBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "nekoBean", + "columnName": "nekoBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "configBean", + "columnName": "configBean", + "affinity": "BLOB", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "groupId", + "unique": false, + "columnNames": [ + "groupId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `groupId` ON `${TABLE_NAME}` (`groupId`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "rules", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `userOrder` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `domains` TEXT NOT NULL, `ip` TEXT NOT NULL, `port` TEXT NOT NULL, `sourcePort` TEXT NOT NULL, `network` TEXT NOT NULL, `source` TEXT NOT NULL, `protocol` TEXT NOT NULL, `outbound` INTEGER NOT NULL, `packages` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "userOrder", + "columnName": "userOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "enabled", + "columnName": "enabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "domains", + "columnName": "domains", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "ip", + "columnName": "ip", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "port", + "columnName": "port", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sourcePort", + "columnName": "sourcePort", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "network", + "columnName": "network", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "source", + "columnName": "source", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "protocol", + "columnName": "protocol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "outbound", + "columnName": "outbound", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "packages", + "columnName": "packages", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f66fd943df1d9e86d281a2e32c9fdd47')" + ] + } +} \ No newline at end of file diff --git a/app/schemas/io.nekohasekai.sagernet.database.SagerDatabase/2.json b/app/schemas/io.nekohasekai.sagernet.database.SagerDatabase/2.json new file mode 100644 index 0000000..7a87689 --- /dev/null +++ b/app/schemas/io.nekohasekai.sagernet.database.SagerDatabase/2.json @@ -0,0 +1,342 @@ +{ + "formatVersion": 1, + "database": { + "version": 2, + "identityHash": "062104587ad7088bb9926683389e995d", + "entities": [ + { + "tableName": "proxy_groups", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `userOrder` INTEGER NOT NULL, `ungrouped` INTEGER NOT NULL, `name` TEXT, `type` INTEGER NOT NULL, `subscription` BLOB, `order` INTEGER NOT NULL, `isSelector` INTEGER NOT NULL, `frontProxy` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userOrder", + "columnName": "userOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ungrouped", + "columnName": "ungrouped", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subscription", + "columnName": "subscription", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isSelector", + "columnName": "isSelector", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "frontProxy", + "columnName": "frontProxy", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "proxy_entities", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `groupId` INTEGER NOT NULL, `type` INTEGER NOT NULL, `userOrder` INTEGER NOT NULL, `tx` INTEGER NOT NULL, `rx` INTEGER NOT NULL, `status` INTEGER NOT NULL, `ping` INTEGER NOT NULL, `uuid` TEXT NOT NULL, `error` TEXT, `socksBean` BLOB, `httpBean` BLOB, `ssBean` BLOB, `vmessBean` BLOB, `trojanBean` BLOB, `trojanGoBean` BLOB, `naiveBean` BLOB, `hysteriaBean` BLOB, `tuicBean` BLOB, `sshBean` BLOB, `wgBean` BLOB, `chainBean` BLOB, `nekoBean` BLOB, `configBean` BLOB)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "groupId", + "columnName": "groupId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userOrder", + "columnName": "userOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "tx", + "columnName": "tx", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "rx", + "columnName": "rx", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ping", + "columnName": "ping", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "uuid", + "columnName": "uuid", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "error", + "columnName": "error", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "socksBean", + "columnName": "socksBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "httpBean", + "columnName": "httpBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "ssBean", + "columnName": "ssBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "vmessBean", + "columnName": "vmessBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "trojanBean", + "columnName": "trojanBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "trojanGoBean", + "columnName": "trojanGoBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "naiveBean", + "columnName": "naiveBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "hysteriaBean", + "columnName": "hysteriaBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "tuicBean", + "columnName": "tuicBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "sshBean", + "columnName": "sshBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "wgBean", + "columnName": "wgBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "chainBean", + "columnName": "chainBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "nekoBean", + "columnName": "nekoBean", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "configBean", + "columnName": "configBean", + "affinity": "BLOB", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "groupId", + "unique": false, + "columnNames": [ + "groupId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `groupId` ON `${TABLE_NAME}` (`groupId`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "rules", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `userOrder` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `domains` TEXT NOT NULL, `ip` TEXT NOT NULL, `port` TEXT NOT NULL, `sourcePort` TEXT NOT NULL, `network` TEXT NOT NULL, `source` TEXT NOT NULL, `protocol` TEXT NOT NULL, `outbound` INTEGER NOT NULL, `packages` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "userOrder", + "columnName": "userOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "enabled", + "columnName": "enabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "domains", + "columnName": "domains", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "ip", + "columnName": "ip", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "port", + "columnName": "port", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sourcePort", + "columnName": "sourcePort", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "network", + "columnName": "network", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "source", + "columnName": "source", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "protocol", + "columnName": "protocol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "outbound", + "columnName": "outbound", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "packages", + "columnName": "packages", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '062104587ad7088bb9926683389e995d')" + ] + } +} \ No newline at end of file diff --git a/app/schemas/io.nekohasekai.sagernet.database.preference.PublicDatabase/1.json b/app/schemas/io.nekohasekai.sagernet.database.preference.PublicDatabase/1.json new file mode 100644 index 0000000..4986920 --- /dev/null +++ b/app/schemas/io.nekohasekai.sagernet.database.preference.PublicDatabase/1.json @@ -0,0 +1,46 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "f1aab1fb633378621635c344dbc8ac7b", + "entities": [ + { + "tableName": "KeyValuePair", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`key` TEXT NOT NULL, `valueType` INTEGER NOT NULL, `value` BLOB NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "key", + "columnName": "key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "valueType", + "columnName": "valueType", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "BLOB", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f1aab1fb633378621635c344dbc8ac7b')" + ] + } +} \ No newline at end of file diff --git a/app/schemas/moe.matsuri.nb4a.TempDatabase/1.json b/app/schemas/moe.matsuri.nb4a.TempDatabase/1.json new file mode 100644 index 0000000..4986920 --- /dev/null +++ b/app/schemas/moe.matsuri.nb4a.TempDatabase/1.json @@ -0,0 +1,46 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "f1aab1fb633378621635c344dbc8ac7b", + "entities": [ + { + "tableName": "KeyValuePair", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`key` TEXT NOT NULL, `valueType` INTEGER NOT NULL, `value` BLOB NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "key", + "columnName": "key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "valueType", + "columnName": "valueType", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "BLOB", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f1aab1fb633378621635c344dbc8ac7b')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/io/nekohasekai/sagernet/Constants.kt b/app/src/main/java/io/nekohasekai/sagernet/Constants.kt index 74df77d..cf42b23 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/Constants.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/Constants.kt @@ -133,6 +133,7 @@ object Key { const val GROUP_NAME = "groupName" const val GROUP_TYPE = "groupType" const val GROUP_ORDER = "groupOrder" + const val GROUP_IS_SELECTOR = "groupIsSelector" const val GROUP_SUBSCRIPTION = "groupSubscription" const val SUBSCRIPTION_LINK = "subscriptionLink" diff --git a/app/src/main/java/io/nekohasekai/sagernet/bg/SagerConnection.kt b/app/src/main/java/io/nekohasekai/sagernet/bg/SagerConnection.kt index bfc0d24..5bce1dd 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/bg/SagerConnection.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/bg/SagerConnection.kt @@ -8,7 +8,10 @@ import android.os.IBinder import android.os.RemoteException import io.nekohasekai.sagernet.Action import io.nekohasekai.sagernet.Key -import io.nekohasekai.sagernet.aidl.* +import io.nekohasekai.sagernet.aidl.ISagerNetService +import io.nekohasekai.sagernet.aidl.ISagerNetServiceCallback +import io.nekohasekai.sagernet.aidl.SpeedDisplayData +import io.nekohasekai.sagernet.aidl.TrafficData import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.ktx.runOnMainDispatcher diff --git a/app/src/main/java/io/nekohasekai/sagernet/bg/proto/BoxInstance.kt b/app/src/main/java/io/nekohasekai/sagernet/bg/proto/BoxInstance.kt index d59b1d2..190a99e 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/bg/proto/BoxInstance.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/bg/proto/BoxInstance.kt @@ -22,9 +22,9 @@ import io.nekohasekai.sagernet.plugin.PluginManager import kotlinx.coroutines.* import libcore.BoxInstance import libcore.Libcore +import moe.matsuri.nb4a.plugin.NekoPluginManager import moe.matsuri.nb4a.proxy.neko.NekoBean import moe.matsuri.nb4a.proxy.neko.NekoJSInterface -import moe.matsuri.nb4a.plugin.NekoPluginManager import moe.matsuri.nb4a.proxy.neko.updateAllConfig import org.json.JSONObject import java.io.File diff --git a/app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt b/app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt index 6f67739..e9aabec 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt @@ -234,6 +234,7 @@ object DataStore : OnPreferenceDataStoreChangeListener { var groupName by profileCacheStore.string(Key.GROUP_NAME) var groupType by profileCacheStore.stringToInt(Key.GROUP_TYPE) var groupOrder by profileCacheStore.stringToInt(Key.GROUP_ORDER) + var groupIsSelector by profileCacheStore.boolean(Key.GROUP_IS_SELECTOR) var subscriptionLink by profileCacheStore.string(Key.SUBSCRIPTION_LINK) var subscriptionForceResolve by profileCacheStore.boolean(Key.SUBSCRIPTION_FORCE_RESOLVE) diff --git a/app/src/main/java/io/nekohasekai/sagernet/database/ProfileManager.kt b/app/src/main/java/io/nekohasekai/sagernet/database/ProfileManager.kt index 31816c2..1bcad16 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/database/ProfileManager.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/database/ProfileManager.kt @@ -2,7 +2,6 @@ package io.nekohasekai.sagernet.database import android.database.sqlite.SQLiteCantOpenDatabaseException import io.nekohasekai.sagernet.R -import io.nekohasekai.sagernet.aidl.SpeedDisplayData import io.nekohasekai.sagernet.aidl.TrafficData import io.nekohasekai.sagernet.fmt.AbstractBean import io.nekohasekai.sagernet.ktx.Logs diff --git a/app/src/main/java/io/nekohasekai/sagernet/database/ProxyEntity.kt b/app/src/main/java/io/nekohasekai/sagernet/database/ProxyEntity.kt index 467b5f6..602d233 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/database/ProxyEntity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/database/ProxyEntity.kt @@ -31,13 +31,9 @@ import io.nekohasekai.sagernet.ktx.app import io.nekohasekai.sagernet.ktx.applyDefaultValues import io.nekohasekai.sagernet.ui.profile.* import moe.matsuri.nb4a.Protocols -import moe.matsuri.nb4a.proxy.neko.* import moe.matsuri.nb4a.proxy.config.ConfigBean import moe.matsuri.nb4a.proxy.config.ConfigSettingActivity -import moe.matsuri.nb4a.proxy.neko.NekoBean -import moe.matsuri.nb4a.proxy.neko.NekoSettingActivity -import moe.matsuri.nb4a.proxy.neko.haveStandardLink -import moe.matsuri.nb4a.proxy.neko.shareLink +import moe.matsuri.nb4a.proxy.neko.* @Entity( tableName = "proxy_entities", indices = [Index("groupId", name = "groupId")] diff --git a/app/src/main/java/io/nekohasekai/sagernet/database/ProxyGroup.kt b/app/src/main/java/io/nekohasekai/sagernet/database/ProxyGroup.kt index 5d2f94f..5f7f753 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/database/ProxyGroup.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/database/ProxyGroup.kt @@ -19,6 +19,8 @@ data class ProxyGroup( var type: Int = GroupType.BASIC, var subscription: SubscriptionBean? = null, var order: Int = GroupOrder.ORIGIN, + var isSelector: Boolean = false, + var frontProxy: Long = 0L ) : Serializable() { @Transient diff --git a/app/src/main/java/io/nekohasekai/sagernet/database/SagerDatabase.kt b/app/src/main/java/io/nekohasekai/sagernet/database/SagerDatabase.kt index a88d9fa..b6fb8c4 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/database/SagerDatabase.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/database/SagerDatabase.kt @@ -15,7 +15,7 @@ import kotlinx.coroutines.launch @Database( entities = [ProxyGroup::class, ProxyEntity::class, RuleEntity::class], - version = 1 + version = 2 ) @TypeConverters(value = [KryoConverters::class, GsonConverters::class]) @GenerateRoomMigrations diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt b/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt index 98231e0..afd575c 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/ConfigBuilder.kt @@ -19,7 +19,6 @@ import io.nekohasekai.sagernet.fmt.socks.buildSingBoxOutboundSocksBean import io.nekohasekai.sagernet.fmt.ssh.SSHBean import io.nekohasekai.sagernet.fmt.ssh.buildSingBoxOutboundSSHBean import io.nekohasekai.sagernet.fmt.tuic.TuicBean -import moe.matsuri.nb4a.SingBoxOptions.* import io.nekohasekai.sagernet.fmt.v2ray.StandardV2RayBean import io.nekohasekai.sagernet.fmt.v2ray.buildSingBoxOutboundStandardV2RayBean import io.nekohasekai.sagernet.fmt.wireguard.WireGuardBean @@ -29,8 +28,9 @@ import io.nekohasekai.sagernet.ktx.mkPort import io.nekohasekai.sagernet.utils.PackageCache import moe.matsuri.nb4a.DNS.applyDNSNetworkSettings import moe.matsuri.nb4a.DNS.makeSingBoxRule -import moe.matsuri.nb4a.proxy.config.ConfigBean +import moe.matsuri.nb4a.SingBoxOptions.* import moe.matsuri.nb4a.plugin.Plugins +import moe.matsuri.nb4a.proxy.config.ConfigBean import moe.matsuri.nb4a.utils.JavaUtil.gson import okhttp3.HttpUrl.Companion.toHttpUrlOrNull diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/KryoConverters.java b/app/src/main/java/io/nekohasekai/sagernet/fmt/KryoConverters.java index f5fce41..8000c02 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/KryoConverters.java +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/KryoConverters.java @@ -24,8 +24,8 @@ import io.nekohasekai.sagernet.fmt.v2ray.VMessBean; import io.nekohasekai.sagernet.fmt.wireguard.WireGuardBean; import io.nekohasekai.sagernet.ktx.KryosKt; import io.nekohasekai.sagernet.ktx.Logs; -import moe.matsuri.nb4a.proxy.neko.NekoBean; import moe.matsuri.nb4a.proxy.config.ConfigBean; +import moe.matsuri.nb4a.proxy.neko.NekoBean; import moe.matsuri.nb4a.utils.JavaUtil; public class KryoConverters { diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/hysteria/HysteriaFmt.kt b/app/src/main/java/io/nekohasekai/sagernet/fmt/hysteria/HysteriaFmt.kt index a355af5..c0e321c 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/hysteria/HysteriaFmt.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/hysteria/HysteriaFmt.kt @@ -4,7 +4,6 @@ import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.fmt.LOCALHOST import io.nekohasekai.sagernet.ktx.* import moe.matsuri.nb4a.SingBoxOptions -import moe.matsuri.nb4a.utils.Util import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import org.json.JSONObject import java.io.File diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/shadowsocks/ShadowsocksFmt.kt b/app/src/main/java/io/nekohasekai/sagernet/fmt/shadowsocks/ShadowsocksFmt.kt index 7d75924..5bd6318 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/shadowsocks/ShadowsocksFmt.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/shadowsocks/ShadowsocksFmt.kt @@ -1,7 +1,7 @@ package io.nekohasekai.sagernet.fmt.shadowsocks -import moe.matsuri.nb4a.SingBoxOptions import io.nekohasekai.sagernet.ktx.* +import moe.matsuri.nb4a.SingBoxOptions import moe.matsuri.nb4a.utils.Util import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import org.json.JSONObject diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/socks/SOCKSFmt.kt b/app/src/main/java/io/nekohasekai/sagernet/fmt/socks/SOCKSFmt.kt index 8f8a1c7..8eee291 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/socks/SOCKSFmt.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/socks/SOCKSFmt.kt @@ -1,7 +1,10 @@ package io.nekohasekai.sagernet.fmt.socks +import io.nekohasekai.sagernet.ktx.decodeBase64UrlSafe +import io.nekohasekai.sagernet.ktx.toLink +import io.nekohasekai.sagernet.ktx.unUrlSafe +import io.nekohasekai.sagernet.ktx.urlSafe import moe.matsuri.nb4a.SingBoxOptions -import io.nekohasekai.sagernet.ktx.* import moe.matsuri.nb4a.utils.NGUtil import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/trojan/TrojanBean.java b/app/src/main/java/io/nekohasekai/sagernet/fmt/trojan/TrojanBean.java index d283dd6..507af40 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/trojan/TrojanBean.java +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/trojan/TrojanBean.java @@ -7,7 +7,6 @@ import com.esotericsoftware.kryo.io.ByteBufferOutput; import org.jetbrains.annotations.NotNull; -import io.nekohasekai.sagernet.fmt.AbstractBean; import io.nekohasekai.sagernet.fmt.KryoConverters; import io.nekohasekai.sagernet.fmt.v2ray.StandardV2RayBean; diff --git a/app/src/main/java/io/nekohasekai/sagernet/fmt/v2ray/V2RayFmt.kt b/app/src/main/java/io/nekohasekai/sagernet/fmt/v2ray/V2RayFmt.kt index 18f6918..6e926de 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/fmt/v2ray/V2RayFmt.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/fmt/v2ray/V2RayFmt.kt @@ -3,8 +3,8 @@ package io.nekohasekai.sagernet.fmt.v2ray import com.google.gson.Gson import io.nekohasekai.sagernet.fmt.http.HttpBean import io.nekohasekai.sagernet.fmt.trojan.TrojanBean -import moe.matsuri.nb4a.SingBoxOptions.* import io.nekohasekai.sagernet.ktx.* +import moe.matsuri.nb4a.SingBoxOptions.* import moe.matsuri.nb4a.utils.NGUtil import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl diff --git a/app/src/main/java/io/nekohasekai/sagernet/ktx/Formats.kt b/app/src/main/java/io/nekohasekai/sagernet/ktx/Formats.kt index ba3f51a..aa28fb8 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ktx/Formats.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ktx/Formats.kt @@ -12,8 +12,8 @@ import io.nekohasekai.sagernet.fmt.socks.parseSOCKS import io.nekohasekai.sagernet.fmt.trojan.parseTrojan import io.nekohasekai.sagernet.fmt.trojan_go.parseTrojanGo import io.nekohasekai.sagernet.fmt.v2ray.parseV2Ray -import moe.matsuri.nb4a.proxy.neko.NekoJSInterface import moe.matsuri.nb4a.plugin.NekoPluginManager +import moe.matsuri.nb4a.proxy.neko.NekoJSInterface import moe.matsuri.nb4a.proxy.neko.parseShareLink import moe.matsuri.nb4a.utils.JavaUtil.gson import moe.matsuri.nb4a.utils.Util diff --git a/app/src/main/java/io/nekohasekai/sagernet/ktx/Layouts.kt b/app/src/main/java/io/nekohasekai/sagernet/ktx/Layouts.kt index 839bbd8..e6d5c01 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ktx/Layouts.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ktx/Layouts.kt @@ -1,7 +1,6 @@ package io.nekohasekai.sagernet.ktx import android.graphics.Rect -import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import io.nekohasekai.sagernet.database.DataStore diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/AppListActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/AppListActivity.kt index 34768ec..3c522fa 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/AppListActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/AppListActivity.kt @@ -38,9 +38,9 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.ensureActive import kotlinx.coroutines.withContext -import moe.matsuri.nb4a.proxy.neko.NekoJSInterface import moe.matsuri.nb4a.plugin.NekoPluginManager import moe.matsuri.nb4a.plugin.Plugins +import moe.matsuri.nb4a.proxy.neko.NekoJSInterface import moe.matsuri.nb4a.ui.Dialogs import kotlin.coroutines.coroutineContext diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/ConfigurationFragment.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/ConfigurationFragment.kt index 37d908f..7565501 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/ConfigurationFragment.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/ConfigurationFragment.kt @@ -56,9 +56,9 @@ import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import moe.matsuri.nb4a.Protocols import moe.matsuri.nb4a.Protocols.getProtocolColor +import moe.matsuri.nb4a.plugin.NekoPluginManager import moe.matsuri.nb4a.proxy.config.ConfigSettingActivity import moe.matsuri.nb4a.proxy.neko.NekoJSInterface -import moe.matsuri.nb4a.plugin.NekoPluginManager import moe.matsuri.nb4a.proxy.neko.NekoSettingActivity import moe.matsuri.nb4a.proxy.neko.canShare import okhttp3.internal.closeQuietly @@ -1467,14 +1467,14 @@ class ConfigurationFragment @JvmOverloads constructor( popup.menuInflater.inflate(R.menu.profile_share_menu, popup.menu) if (proxyEntity.vmessBean == null || proxyEntity.vmessBean!!.isVLESS) { - popup.menu.findItem(R.id.action_group_qr).subMenu.removeItem(R.id.action_v2rayn_qr) - popup.menu.findItem(R.id.action_group_clipboard).subMenu.removeItem(R.id.action_v2rayn_clipboard) + popup.menu.findItem(R.id.action_group_qr).subMenu?.removeItem(R.id.action_v2rayn_qr) + popup.menu.findItem(R.id.action_group_clipboard).subMenu?.removeItem(R.id.action_v2rayn_clipboard) } when { !proxyEntity.haveStandardLink() -> { - popup.menu.findItem(R.id.action_group_qr).subMenu.removeItem(R.id.action_standard_qr) - popup.menu.findItem(R.id.action_group_clipboard).subMenu.removeItem( + popup.menu.findItem(R.id.action_group_qr).subMenu?.removeItem(R.id.action_standard_qr) + popup.menu.findItem(R.id.action_group_clipboard).subMenu?.removeItem( R.id.action_standard_clipboard ) } diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/GroupSettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/GroupSettingsActivity.kt index 7773abc..acc15c7 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/GroupSettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/GroupSettingsActivity.kt @@ -1,20 +1,21 @@ package io.nekohasekai.sagernet.ui import android.annotation.SuppressLint +import android.app.Activity import android.content.DialogInterface +import android.content.Intent import android.os.Bundle import android.os.Parcelable import android.view.Menu import android.view.MenuItem import android.view.View +import androidx.activity.result.contract.ActivityResultContracts import androidx.annotation.LayoutRes import androidx.appcompat.app.AlertDialog import androidx.core.view.ViewCompat import androidx.preference.* import com.github.shadowsocks.plugin.Empty import com.github.shadowsocks.plugin.fragment.AlertDialogFragment -import com.takisoft.preferencex.PreferenceFragmentCompat -import com.takisoft.preferencex.SimpleMenuPreference import io.nekohasekai.sagernet.GroupType import io.nekohasekai.sagernet.Key import io.nekohasekai.sagernet.R @@ -24,8 +25,10 @@ import io.nekohasekai.sagernet.ktx.applyDefaultValues import io.nekohasekai.sagernet.ktx.onMainDispatcher import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher import io.nekohasekai.sagernet.widget.ListListener +import io.nekohasekai.sagernet.widget.OutboundPreference import io.nekohasekai.sagernet.widget.UserAgentPreference import kotlinx.parcelize.Parcelize +import moe.matsuri.nb4a.ui.SimpleMenuPreference @Suppress("UNCHECKED_CAST") class GroupSettingsActivity( @@ -33,10 +36,16 @@ class GroupSettingsActivity( ) : ThemedActivity(resId), OnPreferenceDataStoreChangeListener { + private lateinit var frontProxyPreference: OutboundPreference + fun ProxyGroup.init() { DataStore.groupName = name ?: "" DataStore.groupType = type DataStore.groupOrder = order + DataStore.groupIsSelector = isSelector + DataStore.routeOutboundRule = frontProxy + DataStore.routeOutbound = if (frontProxy >= 0) 3 else 0 + val subscription = subscription ?: SubscriptionBean().applyDefaultValues() DataStore.subscriptionLink = subscription.link DataStore.subscriptionForceResolve = subscription.forceResolve @@ -51,6 +60,8 @@ class GroupSettingsActivity( name = DataStore.groupName.takeIf { it.isNotBlank() } ?: "My group" type = DataStore.groupType order = DataStore.groupOrder + isSelector = DataStore.groupIsSelector + frontProxy = if (DataStore.routeOutbound == 3) DataStore.routeOutboundRule else -1 val isSubscription = type == GroupType.SUBSCRIPTION if (isSubscription) { @@ -77,6 +88,22 @@ class GroupSettingsActivity( ) { addPreferencesFromResource(R.xml.group_preferences) + frontProxyPreference = findPreference(Key.ROUTE_OUTBOUND)!! + frontProxyPreference.apply { + entries = listOf("None", "Select...").toTypedArray() + entryValues = listOf("0", "3").toTypedArray() + setOnPreferenceChangeListener { _, newValue -> + if (newValue.toString() == "3") { + selectProfileForAdd.launch( + Intent(this@GroupSettingsActivity, ProfileSelectActivity::class.java) + ) + false + } else { + true + } + } + } + val groupType = findPreference(Key.GROUP_TYPE)!! val groupSubscription = findPreference(Key.GROUP_SUBSCRIPTION)!! val subscriptionUpdate = findPreference(Key.SUBSCRIPTION_UPDATE)!! @@ -252,7 +279,7 @@ class GroupSettingsActivity( lateinit var activity: GroupSettingsActivity - override fun onCreatePreferencesFix(savedInstanceState: Bundle?, rootKey: String?) { + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { preferenceManager.preferenceDataStore = DataStore.profileCacheStore activity.apply { createPreferences(savedInstanceState, rootKey) @@ -312,4 +339,20 @@ class GroupSettingsActivity( } + val selectProfileForAdd = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { + if (it.resultCode == Activity.RESULT_OK) runOnDefaultDispatcher { + val profile = ProfileManager.getProfile( + it.data!!.getLongExtra( + ProfileSelectActivity.EXTRA_PROFILE_ID, 0 + ) + ) ?: return@runOnDefaultDispatcher + DataStore.routeOutboundRule = profile.id + onMainDispatcher { + frontProxyPreference.value = "3" + } + } + } + } \ No newline at end of file diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/MainActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/MainActivity.kt index 4f009ed..8f4f8e8 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/MainActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/MainActivity.kt @@ -30,7 +30,6 @@ import io.nekohasekai.sagernet.group.GroupInterfaceAdapter import io.nekohasekai.sagernet.group.GroupUpdater import io.nekohasekai.sagernet.ktx.* import io.nekohasekai.sagernet.widget.ListHolderListener -import kotlinx.coroutines.launch import libcore.Libcore import moe.matsuri.nb4a.utils.Util import java.text.SimpleDateFormat diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/RouteSettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/RouteSettingsActivity.kt index 433a65c..460a48d 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/RouteSettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/RouteSettingsActivity.kt @@ -17,10 +17,10 @@ import androidx.core.view.ViewCompat import androidx.preference.EditTextPreference import androidx.preference.Preference import androidx.preference.PreferenceDataStore +import androidx.preference.PreferenceFragmentCompat import com.github.shadowsocks.plugin.Empty import com.github.shadowsocks.plugin.fragment.AlertDialogFragment import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.takisoft.preferencex.PreferenceFragmentCompat import io.nekohasekai.sagernet.Key import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.DataStore @@ -308,7 +308,7 @@ class RouteSettingsActivity( lateinit var activity: RouteSettingsActivity - override fun onCreatePreferencesFix(savedInstanceState: Bundle?, rootKey: String?) { + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { preferenceManager.preferenceDataStore = DataStore.profileCacheStore activity.apply { createPreferences(savedInstanceState, rootKey) diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/SettingsPreferenceFragment.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/SettingsPreferenceFragment.kt index 78fceb7..d2831ff 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/SettingsPreferenceFragment.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/SettingsPreferenceFragment.kt @@ -7,13 +7,8 @@ import android.view.View import android.view.inputmethod.EditorInfo import android.widget.EditText import androidx.core.app.ActivityCompat -import androidx.preference.EditTextPreference -import androidx.preference.MultiSelectListPreference -import androidx.preference.Preference -import androidx.preference.SwitchPreference +import androidx.preference.* import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.takisoft.preferencex.PreferenceFragmentCompat -import com.takisoft.preferencex.SimpleMenuPreference import io.nekohasekai.sagernet.Key import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.SagerNet @@ -25,8 +20,8 @@ import io.nekohasekai.sagernet.widget.AppListPreference import moe.matsuri.nb4a.Protocols import moe.matsuri.nb4a.ui.ColorPickerPreference import moe.matsuri.nb4a.ui.LongClickMenuPreference -import moe.matsuri.nb4a.ui.LongClickSwitchPreference import moe.matsuri.nb4a.ui.MTUPreference +import moe.matsuri.nb4a.ui.SimpleMenuPreference class SettingsPreferenceFragment : PreferenceFragmentCompat() { @@ -44,7 +39,7 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() { true } - override fun onCreatePreferencesFix(savedInstanceState: Bundle?, rootKey: String?) { + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { preferenceManager.preferenceDataStore = DataStore.configurationStore DataStore.initGlobal() addPreferencesFromResource(R.xml.global_preferences) diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/ChainSettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/ChainSettingsActivity.kt index 32542e2..ed079f3 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/ChainSettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/ChainSettingsActivity.kt @@ -13,11 +13,11 @@ import androidx.activity.result.component1 import androidx.activity.result.component2 import androidx.activity.result.contract.ActivityResultContracts import androidx.core.view.isVisible +import androidx.preference.PreferenceFragmentCompat import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.takisoft.preferencex.PreferenceFragmentCompat import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.database.ProfileManager diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/HysteriaSettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/HysteriaSettingsActivity.kt index 6282a21..02534b5 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/HysteriaSettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/HysteriaSettingsActivity.kt @@ -2,14 +2,14 @@ package io.nekohasekai.sagernet.ui.profile import android.os.Bundle import androidx.preference.EditTextPreference -import com.takisoft.preferencex.PreferenceFragmentCompat -import com.takisoft.preferencex.SimpleMenuPreference +import androidx.preference.PreferenceFragmentCompat import io.nekohasekai.sagernet.Key import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.database.preference.EditTextPreferenceModifiers import io.nekohasekai.sagernet.fmt.hysteria.HysteriaBean import io.nekohasekai.sagernet.ktx.applyDefaultValues +import moe.matsuri.nb4a.ui.SimpleMenuPreference class HysteriaSettingsActivity : ProfileSettingsActivity() { diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/NaiveSettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/NaiveSettingsActivity.kt index 39f6c1f..0c0068f 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/NaiveSettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/NaiveSettingsActivity.kt @@ -2,7 +2,7 @@ package io.nekohasekai.sagernet.ui.profile import android.os.Bundle import androidx.preference.EditTextPreference -import com.takisoft.preferencex.PreferenceFragmentCompat +import androidx.preference.PreferenceFragmentCompat import io.nekohasekai.sagernet.Key import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.DataStore diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/ProfileSettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/ProfileSettingsActivity.kt index baf9246..8b1da23 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/ProfileSettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/ProfileSettingsActivity.kt @@ -21,12 +21,12 @@ import androidx.core.view.isVisible import androidx.preference.EditTextPreference import androidx.preference.Preference import androidx.preference.PreferenceDataStore +import androidx.preference.PreferenceFragmentCompat import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.input.input import com.github.shadowsocks.plugin.Empty import com.github.shadowsocks.plugin.fragment.AlertDialogFragment import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.takisoft.preferencex.PreferenceFragmentCompat import io.nekohasekai.sagernet.* import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.database.GroupManager @@ -213,7 +213,7 @@ abstract class ProfileSettingsActivity( lateinit var activity: ProfileSettingsActivity<*> - override fun onCreatePreferencesFix(savedInstanceState: Bundle?, rootKey: String?) { + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { preferenceManager.preferenceDataStore = DataStore.profileCacheStore activity.apply { createPreferences(savedInstanceState, rootKey) diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/SSHSettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/SSHSettingsActivity.kt index dcead13..feed75f 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/SSHSettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/SSHSettingsActivity.kt @@ -2,13 +2,13 @@ package io.nekohasekai.sagernet.ui.profile import android.os.Bundle import androidx.preference.EditTextPreference -import com.takisoft.preferencex.PreferenceFragmentCompat -import com.takisoft.preferencex.SimpleMenuPreference +import androidx.preference.PreferenceFragmentCompat import io.nekohasekai.sagernet.Key import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.database.preference.EditTextPreferenceModifiers import io.nekohasekai.sagernet.fmt.ssh.SSHBean +import moe.matsuri.nb4a.ui.SimpleMenuPreference class SSHSettingsActivity : ProfileSettingsActivity() { diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/ShadowsocksSettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/ShadowsocksSettingsActivity.kt index bb6de7e..cdf3ccd 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/ShadowsocksSettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/ShadowsocksSettingsActivity.kt @@ -2,7 +2,7 @@ package io.nekohasekai.sagernet.ui.profile import android.os.Bundle import androidx.preference.EditTextPreference -import com.takisoft.preferencex.PreferenceFragmentCompat +import androidx.preference.PreferenceFragmentCompat import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.database.preference.EditTextPreferenceModifiers diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/SocksSettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/SocksSettingsActivity.kt index 286ecad..3d5d8e3 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/SocksSettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/SocksSettingsActivity.kt @@ -2,14 +2,13 @@ package io.nekohasekai.sagernet.ui.profile import android.os.Bundle import androidx.preference.EditTextPreference -import androidx.preference.PreferenceCategory -import com.takisoft.preferencex.PreferenceFragmentCompat -import com.takisoft.preferencex.SimpleMenuPreference +import androidx.preference.PreferenceFragmentCompat import io.nekohasekai.sagernet.Key import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.database.preference.EditTextPreferenceModifiers import io.nekohasekai.sagernet.fmt.socks.SOCKSBean +import moe.matsuri.nb4a.ui.SimpleMenuPreference class SocksSettingsActivity : ProfileSettingsActivity() { override fun createEntity() = SOCKSBean() diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/StandardV2RaySettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/StandardV2RaySettingsActivity.kt index ebae666..9b9cdbf 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/StandardV2RaySettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/StandardV2RaySettingsActivity.kt @@ -3,8 +3,7 @@ package io.nekohasekai.sagernet.ui.profile import android.os.Bundle import androidx.preference.EditTextPreference import androidx.preference.PreferenceCategory -import com.takisoft.preferencex.PreferenceFragmentCompat -import com.takisoft.preferencex.SimpleMenuPreference +import androidx.preference.PreferenceFragmentCompat import io.nekohasekai.sagernet.Key import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.preference.EditTextPreferenceModifiers @@ -12,10 +11,10 @@ import io.nekohasekai.sagernet.fmt.http.HttpBean import io.nekohasekai.sagernet.fmt.trojan.TrojanBean import io.nekohasekai.sagernet.fmt.v2ray.StandardV2RayBean import io.nekohasekai.sagernet.fmt.v2ray.VMessBean -import io.nekohasekai.sagernet.ktx.Logs import moe.matsuri.nb4a.proxy.PreferenceBinding import moe.matsuri.nb4a.proxy.PreferenceBindingManager import moe.matsuri.nb4a.proxy.Type +import moe.matsuri.nb4a.ui.SimpleMenuPreference abstract class StandardV2RaySettingsActivity : ProfileSettingsActivity() { diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/TrojanGoSettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/TrojanGoSettingsActivity.kt index 45aa98d..2a0a6b8 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/TrojanGoSettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/TrojanGoSettingsActivity.kt @@ -3,14 +3,14 @@ package io.nekohasekai.sagernet.ui.profile import android.os.Bundle import androidx.preference.EditTextPreference import androidx.preference.PreferenceCategory -import com.takisoft.preferencex.PreferenceFragmentCompat -import com.takisoft.preferencex.SimpleMenuPreference +import androidx.preference.PreferenceFragmentCompat import io.nekohasekai.sagernet.Key import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.database.preference.EditTextPreferenceModifiers import io.nekohasekai.sagernet.fmt.trojan_go.TrojanGoBean import io.nekohasekai.sagernet.ktx.app +import moe.matsuri.nb4a.ui.SimpleMenuPreference class TrojanGoSettingsActivity : ProfileSettingsActivity() { diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/TuicSettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/TuicSettingsActivity.kt index 5f81a6c..b548499 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/TuicSettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/TuicSettingsActivity.kt @@ -1,11 +1,9 @@ package io.nekohasekai.sagernet.ui.profile import android.os.Bundle -import android.widget.Switch import androidx.preference.EditTextPreference +import androidx.preference.PreferenceFragmentCompat import androidx.preference.SwitchPreference -import com.takisoft.preferencex.PreferenceFragmentCompat -import com.takisoft.preferencex.SimpleMenuPreference import io.nekohasekai.sagernet.Key import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.DataStore diff --git a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/WireGuardSettingsActivity.kt b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/WireGuardSettingsActivity.kt index 0673aa7..f603ea7 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/ui/profile/WireGuardSettingsActivity.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/ui/profile/WireGuardSettingsActivity.kt @@ -2,7 +2,7 @@ package io.nekohasekai.sagernet.ui.profile import android.os.Bundle import androidx.preference.EditTextPreference -import com.takisoft.preferencex.PreferenceFragmentCompat +import androidx.preference.PreferenceFragmentCompat import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.preference.EditTextPreferenceModifiers import io.nekohasekai.sagernet.fmt.wireguard.WireGuardBean diff --git a/app/src/main/java/io/nekohasekai/sagernet/widget/GroupPreference.kt b/app/src/main/java/io/nekohasekai/sagernet/widget/GroupPreference.kt index e27dff9..6cb3a1f 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/widget/GroupPreference.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/widget/GroupPreference.kt @@ -2,20 +2,14 @@ package io.nekohasekai.sagernet.widget import android.content.Context import android.util.AttributeSet -import com.takisoft.preferencex.SimpleMenuPreference +import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.SagerDatabase +import moe.matsuri.nb4a.ui.SimpleMenuPreference -class GroupPreference : SimpleMenuPreference { - - constructor(context: Context?) : super(context) - constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) - constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super( - context, attrs, defStyle - ) - - constructor( - context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int - ) : super(context, attrs, defStyleAttr, defStyleRes) +class GroupPreference +@JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyle: Int = R.attr.dropdownPreferenceStyle +) : SimpleMenuPreference(context, attrs, defStyle, 0) { init { val groups = SagerDatabase.groupDao.allGroups() diff --git a/app/src/main/java/io/nekohasekai/sagernet/widget/LinkOrContentPreference.kt b/app/src/main/java/io/nekohasekai/sagernet/widget/LinkOrContentPreference.kt index 8fdf1f2..dffa94b 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/widget/LinkOrContentPreference.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/widget/LinkOrContentPreference.kt @@ -3,26 +3,26 @@ package io.nekohasekai.sagernet.widget import android.content.Context import android.net.Uri import android.util.AttributeSet +import androidx.core.content.res.TypedArrayUtils import androidx.core.widget.addTextChangedListener +import androidx.preference.EditTextPreference import com.google.android.material.textfield.TextInputLayout -import com.takisoft.preferencex.EditTextPreference import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.ktx.app import io.nekohasekai.sagernet.ktx.readableMessage import okhttp3.HttpUrl.Companion.toHttpUrl -class LinkOrContentPreference : EditTextPreference { - - constructor(context: Context?) : super(context) - constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) - constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super( - context, attrs, defStyleAttr - ) - - constructor( - context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int - ) : super(context, attrs, defStyleAttr, defStyleRes) - +class LinkOrContentPreference +@JvmOverloads +constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = TypedArrayUtils.getAttr( + context, R.attr.editTextPreferenceStyle, + android.R.attr.editTextPreferenceStyle + ), + defStyleRes: Int = 0 +) : EditTextPreference(context, attrs, defStyleAttr, defStyleRes) { init { dialogLayoutResource = R.layout.layout_link_dialog diff --git a/app/src/main/java/io/nekohasekai/sagernet/widget/LinkPreference.kt b/app/src/main/java/io/nekohasekai/sagernet/widget/LinkPreference.kt index 9397669..110743e 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/widget/LinkPreference.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/widget/LinkPreference.kt @@ -2,50 +2,28 @@ package io.nekohasekai.sagernet.widget import android.content.Context import android.util.AttributeSet +import androidx.core.content.res.TypedArrayUtils import androidx.core.widget.addTextChangedListener +import androidx.preference.EditTextPreference import com.google.android.material.textfield.TextInputLayout -import com.takisoft.preferencex.EditTextPreference import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.ktx.app import io.nekohasekai.sagernet.ktx.readableMessage import okhttp3.HttpUrl.Companion.toHttpUrl -class LinkPreference : EditTextPreference { +class LinkPreference +@JvmOverloads +constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = TypedArrayUtils.getAttr( + context, R.attr.editTextPreferenceStyle, + android.R.attr.editTextPreferenceStyle + ), + defStyleRes: Int = 0 +) : EditTextPreference(context, attrs, defStyleAttr, defStyleRes) { - var defaultValue: String? = null - - constructor(context: Context) : this(context, null) - - constructor( - context: Context, - attrs: AttributeSet?, - ) : this(context, attrs, com.takisoft.preferencex.R.attr.editTextPreferenceStyle) - - constructor( - context: Context, - attrs: AttributeSet?, - defStyleAttr: Int, - ) : this(context, attrs, defStyleAttr, 0) - - constructor( - context: Context, - attrs: AttributeSet?, - defStyleAttr: Int, - defStyleRes: Int, - ) : super(context, attrs, defStyleAttr, defStyleRes) { - val a = context.obtainStyledAttributes( - attrs, R.styleable.Preference, defStyleAttr, defStyleRes - ) - if (a.hasValue(androidx.preference.R.styleable.Preference_defaultValue)) { - defaultValue = onGetDefaultValue( - a, androidx.preference.R.styleable.Preference_defaultValue - )?.toString() - } else if (a.hasValue(androidx.preference.R.styleable.Preference_android_defaultValue)) { - defaultValue = onGetDefaultValue( - a, androidx.preference.R.styleable.Preference_android_defaultValue - )?.toString() - } - } +// var defaultValue: String? = null init { dialogLayoutResource = R.layout.layout_link_dialog @@ -79,7 +57,7 @@ class LinkPreference : EditTextPreference { setOnPreferenceChangeListener { _, newValue -> if ((newValue as String).isBlank()) { - text = defaultValue +// text = defaultValue false } else try { newValue.toHttpUrl() diff --git a/app/src/main/java/io/nekohasekai/sagernet/widget/OutboundPreference.kt b/app/src/main/java/io/nekohasekai/sagernet/widget/OutboundPreference.kt index 6adf26b..b4576ff 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/widget/OutboundPreference.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/widget/OutboundPreference.kt @@ -2,27 +2,15 @@ package io.nekohasekai.sagernet.widget import android.content.Context import android.util.AttributeSet -import com.takisoft.preferencex.SimpleMenuPreference import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.database.ProfileManager +import moe.matsuri.nb4a.ui.SimpleMenuPreference -class OutboundPreference : SimpleMenuPreference { - - constructor(context: Context?) : super(context) - constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) - constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super( - context, - attrs, - defStyle - ) - - constructor( - context: Context?, - attrs: AttributeSet?, - defStyleAttr: Int, - defStyleRes: Int - ) : super(context, attrs, defStyleAttr, defStyleRes) +class OutboundPreference +@JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyle: Int = R.attr.dropdownPreferenceStyle +) : SimpleMenuPreference(context, attrs, defStyle, 0) { init { setEntries(R.array.outbound_entry) diff --git a/app/src/main/java/io/nekohasekai/sagernet/widget/UserAgentPreference.kt b/app/src/main/java/io/nekohasekai/sagernet/widget/UserAgentPreference.kt index 2ec9ffc..459535d 100644 --- a/app/src/main/java/io/nekohasekai/sagernet/widget/UserAgentPreference.kt +++ b/app/src/main/java/io/nekohasekai/sagernet/widget/UserAgentPreference.kt @@ -2,20 +2,17 @@ package io.nekohasekai.sagernet.widget import android.content.Context import android.util.AttributeSet -import com.takisoft.preferencex.EditTextPreference +import androidx.core.content.res.TypedArrayUtils +import androidx.preference.EditTextPreference +import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.ktx.USER_AGENT -class UserAgentPreference : EditTextPreference { - - constructor(context: Context?) : super(context) - constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) - constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super( - context, attrs, defStyle +class UserAgentPreference +@JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyle: Int = TypedArrayUtils.getAttr( + context, R.attr.editTextPreferenceStyle, android.R.attr.editTextPreferenceStyle ) - - constructor( - context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int - ) : super(context, attrs, defStyleAttr, defStyleRes) +) : EditTextPreference(context, attrs, defStyle) { public override fun notifyChanged() { super.notifyChanged() diff --git a/app/src/main/java/moe/matsuri/nb4a/plugin/Plugins.kt b/app/src/main/java/moe/matsuri/nb4a/plugin/Plugins.kt index e07adc2..677710d 100644 --- a/app/src/main/java/moe/matsuri/nb4a/plugin/Plugins.kt +++ b/app/src/main/java/moe/matsuri/nb4a/plugin/Plugins.kt @@ -8,7 +8,6 @@ import android.net.Uri import android.os.Build import android.widget.Toast import io.nekohasekai.sagernet.SagerNet -import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.plugin.PluginManager.loadString import io.nekohasekai.sagernet.utils.PackageCache diff --git a/app/src/main/java/moe/matsuri/nb4a/proxy/PreferenceBinding.kt b/app/src/main/java/moe/matsuri/nb4a/proxy/PreferenceBinding.kt index 185a103..6896d3d 100644 --- a/app/src/main/java/moe/matsuri/nb4a/proxy/PreferenceBinding.kt +++ b/app/src/main/java/moe/matsuri/nb4a/proxy/PreferenceBinding.kt @@ -1,9 +1,7 @@ package moe.matsuri.nb4a.proxy import androidx.preference.Preference -import com.takisoft.preferencex.EditTextPreference -import com.takisoft.preferencex.PreferenceFragmentCompat -import com.takisoft.preferencex.SimpleMenuPreference +import androidx.preference.PreferenceFragmentCompat import io.nekohasekai.sagernet.database.DataStore import io.nekohasekai.sagernet.ktx.Logs import io.nekohasekai.sagernet.ktx.readableMessage diff --git a/app/src/main/java/moe/matsuri/nb4a/proxy/PreferenceBindingManager.kt b/app/src/main/java/moe/matsuri/nb4a/proxy/PreferenceBindingManager.kt index 5da4856..2b64c95 100644 --- a/app/src/main/java/moe/matsuri/nb4a/proxy/PreferenceBindingManager.kt +++ b/app/src/main/java/moe/matsuri/nb4a/proxy/PreferenceBindingManager.kt @@ -1,6 +1,7 @@ package moe.matsuri.nb4a.proxy -import com.takisoft.preferencex.PreferenceFragmentCompat +import androidx.preference.PreferenceFragmentCompat + class PreferenceBindingManager { val items = mutableListOf() diff --git a/app/src/main/java/moe/matsuri/nb4a/proxy/config/ConfigSettingActivity.kt b/app/src/main/java/moe/matsuri/nb4a/proxy/config/ConfigSettingActivity.kt index 246ec65..8721579 100644 --- a/app/src/main/java/moe/matsuri/nb4a/proxy/config/ConfigSettingActivity.kt +++ b/app/src/main/java/moe/matsuri/nb4a/proxy/config/ConfigSettingActivity.kt @@ -1,10 +1,10 @@ package moe.matsuri.nb4a.proxy.config import android.os.Bundle +import androidx.preference.EditTextPreference import androidx.preference.PreferenceDataStore +import androidx.preference.PreferenceFragmentCompat import androidx.preference.SwitchPreference -import com.takisoft.preferencex.EditTextPreference -import com.takisoft.preferencex.PreferenceFragmentCompat import io.nekohasekai.sagernet.Key import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.DataStore diff --git a/app/src/main/java/moe/matsuri/nb4a/proxy/neko/NekoJSInterface.kt b/app/src/main/java/moe/matsuri/nb4a/proxy/neko/NekoJSInterface.kt index 35b5712..df165c7 100644 --- a/app/src/main/java/moe/matsuri/nb4a/proxy/neko/NekoJSInterface.kt +++ b/app/src/main/java/moe/matsuri/nb4a/proxy/neko/NekoJSInterface.kt @@ -5,7 +5,6 @@ import android.webkit.* import android.widget.Toast import androidx.preference.Preference import androidx.preference.PreferenceScreen -import com.takisoft.preferencex.SimpleMenuPreference import io.nekohasekai.sagernet.BuildConfig import io.nekohasekai.sagernet.SagerNet import io.nekohasekai.sagernet.database.DataStore @@ -14,6 +13,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.withContext import moe.matsuri.nb4a.plugin.NekoPluginManager +import moe.matsuri.nb4a.ui.SimpleMenuPreference import moe.matsuri.nb4a.utils.JavaUtil import moe.matsuri.nb4a.utils.Util import moe.matsuri.nb4a.utils.WebViewUtil diff --git a/app/src/main/java/moe/matsuri/nb4a/proxy/neko/NekoPreferenceInflater.kt b/app/src/main/java/moe/matsuri/nb4a/proxy/neko/NekoPreferenceInflater.kt index 5453f5e..cd2fdff 100644 --- a/app/src/main/java/moe/matsuri/nb4a/proxy/neko/NekoPreferenceInflater.kt +++ b/app/src/main/java/moe/matsuri/nb4a/proxy/neko/NekoPreferenceInflater.kt @@ -1,17 +1,13 @@ package moe.matsuri.nb4a.proxy.neko -import androidx.preference.Preference -import androidx.preference.PreferenceScreen -import androidx.preference.SwitchPreference -import com.takisoft.preferencex.EditTextPreference -import com.takisoft.preferencex.PreferenceCategory -import com.takisoft.preferencex.SimpleMenuPreference +import androidx.preference.* import io.nekohasekai.sagernet.database.preference.EditTextPreferenceModifiers import io.nekohasekai.sagernet.ktx.forEach import io.nekohasekai.sagernet.ktx.getStr import io.nekohasekai.sagernet.ui.profile.ProfileSettingsActivity import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import moe.matsuri.nb4a.ui.SimpleMenuPreference import moe.matsuri.nb4a.utils.getDrawableByName import org.json.JSONArray import org.json.JSONObject @@ -37,14 +33,24 @@ object NekoPreferenceInflater { "EditTextPreference" -> { p = EditTextPreference(context).apply { when (any.getStr("summaryProvider")) { - null -> summaryProvider = androidx.preference.EditTextPreference.SimpleSummaryProvider.getInstance() - "PasswordSummaryProvider" -> summaryProvider = ProfileSettingsActivity.PasswordSummaryProvider + null -> summaryProvider = + EditTextPreference.SimpleSummaryProvider.getInstance() + "PasswordSummaryProvider" -> summaryProvider = + ProfileSettingsActivity.PasswordSummaryProvider } when (any.getStr("EditTextPreferenceModifiers")) { - "Monospace" -> onBindEditTextListener = EditTextPreferenceModifiers.Monospace - "Hosts" -> onBindEditTextListener = EditTextPreferenceModifiers.Hosts - "Port" -> onBindEditTextListener = EditTextPreferenceModifiers.Port - "Number" -> onBindEditTextListener = EditTextPreferenceModifiers.Number + "Monospace" -> setOnBindEditTextListener( + EditTextPreferenceModifiers.Monospace + ) + "Hosts" -> setOnBindEditTextListener( + EditTextPreferenceModifiers.Hosts + ) + "Port" -> setOnBindEditTextListener( + EditTextPreferenceModifiers.Port + ) + "Number" -> setOnBindEditTextListener( + EditTextPreferenceModifiers.Number + ) } } } @@ -53,7 +59,6 @@ object NekoPreferenceInflater { } "SimpleMenuPreference" -> { p = SimpleMenuPreference(context).apply { - summaryProvider = androidx.preference.ListPreference.SimpleSummaryProvider.getInstance() val entries = any.optJSONObject("entries") if (entries != null) setMenu(this, entries) } @@ -85,8 +90,8 @@ object NekoPreferenceInflater { menuEntries.add(b as String) } entries.apply { - p.setEntries(menuEntries.toTypedArray()) - p.setEntryValues(menuEntryValues.toTypedArray()) + p.entries = menuEntries.toTypedArray() + p.entryValues = menuEntryValues.toTypedArray() } } } \ No newline at end of file diff --git a/app/src/main/java/moe/matsuri/nb4a/proxy/neko/NekoSettingActivity.kt b/app/src/main/java/moe/matsuri/nb4a/proxy/neko/NekoSettingActivity.kt index 0f3eb7c..e167fd6 100644 --- a/app/src/main/java/moe/matsuri/nb4a/proxy/neko/NekoSettingActivity.kt +++ b/app/src/main/java/moe/matsuri/nb4a/proxy/neko/NekoSettingActivity.kt @@ -4,7 +4,7 @@ import android.os.Bundle import android.view.View import androidx.core.view.isVisible import androidx.preference.PreferenceDataStore -import com.takisoft.preferencex.PreferenceFragmentCompat +import androidx.preference.PreferenceFragmentCompat import io.nekohasekai.sagernet.Key import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.database.DataStore diff --git a/app/src/main/java/moe/matsuri/nb4a/ui/LongClickMenuPreference.kt b/app/src/main/java/moe/matsuri/nb4a/ui/LongClickMenuPreference.kt index a0e7ab8..cff260b 100644 --- a/app/src/main/java/moe/matsuri/nb4a/ui/LongClickMenuPreference.kt +++ b/app/src/main/java/moe/matsuri/nb4a/ui/LongClickMenuPreference.kt @@ -4,18 +4,12 @@ import android.content.Context import android.util.AttributeSet import android.view.View import androidx.preference.PreferenceViewHolder -import com.takisoft.preferencex.SimpleMenuPreference import io.nekohasekai.sagernet.R class LongClickMenuPreference @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyleAttr: Int = com.takisoft.preferencex.simplemenu.R.attr.simpleMenuPreferenceStyle, - defStyleRes: Int = R.style.Preference_SimpleMenuPreference -) : SimpleMenuPreference( - context, attrs, defStyleAttr, defStyleRes -) { + context: Context, attrs: AttributeSet? = null, defStyle: Int = R.attr.dropdownPreferenceStyle +) : SimpleMenuPreference(context, attrs, defStyle, 0) { private var mLongClickListener: View.OnLongClickListener? = null override fun onBindViewHolder(holder: PreferenceViewHolder) { diff --git a/app/src/main/java/moe/matsuri/nb4a/ui/MTUPreference.kt b/app/src/main/java/moe/matsuri/nb4a/ui/MTUPreference.kt index cbcdf8d..b3f14e9 100644 --- a/app/src/main/java/moe/matsuri/nb4a/ui/MTUPreference.kt +++ b/app/src/main/java/moe/matsuri/nb4a/ui/MTUPreference.kt @@ -5,21 +5,15 @@ import android.util.AttributeSet import android.view.View import android.view.inputmethod.EditorInfo import android.widget.EditText +import androidx.core.content.res.TypedArrayUtils import androidx.preference.PreferenceViewHolder import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.takisoft.preferencex.SimpleMenuPreference - -class MTUPreference : SimpleMenuPreference { - constructor(context: Context?) : super(context) - constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) - constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super( - context, attrs, defStyleAttr - ) - - constructor( - context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int - ) : super(context, attrs, defStyleAttr, defStyleRes) +import io.nekohasekai.sagernet.R +class MTUPreference +@JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyle: Int = R.attr.dropdownPreferenceStyle +) : SimpleMenuPreference(context, attrs, defStyle, 0) { init { setSummaryProvider { value.toString() diff --git a/app/src/main/java/moe/matsuri/nb4a/ui/SimpleMenuPreference.kt b/app/src/main/java/moe/matsuri/nb4a/ui/SimpleMenuPreference.kt new file mode 100644 index 0000000..19a913d --- /dev/null +++ b/app/src/main/java/moe/matsuri/nb4a/ui/SimpleMenuPreference.kt @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package moe.matsuri.nb4a.ui + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.Spinner +import androidx.core.content.ContextCompat +import androidx.preference.DropDownPreference +import androidx.preference.PreferenceViewHolder +import io.nekohasekai.sagernet.R +import io.nekohasekai.sagernet.ktx.getColorAttr + +/** + * Bend [DropDownPreference] to support + * [Simple Menus](https://material.google.com/components/menus.html#menus-behavior). + */ + + +open class SimpleMenuPreference +@JvmOverloads constructor( + context: Context?, + attrs: AttributeSet? = null, + defStyleAttr: Int = androidx.preference.R.attr.dropdownPreferenceStyle, + defStyleRes: Int = 0 +) : DropDownPreference(context!!, attrs, defStyleAttr, defStyleRes) { + + private lateinit var mAdapter: SimpleMenuAdapter + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + val mSpinner = holder.itemView.findViewById(R.id.spinner) + mSpinner.layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT + } + + override fun createAdapter(): ArrayAdapter { + mAdapter = SimpleMenuAdapter(getContext(), R.layout.simple_menu_dropdown_item) + return mAdapter + } + + override fun setValue(value: String?) { + super.setValue(value) + if (::mAdapter.isInitialized) { + mAdapter.currentPosition = entryValues.indexOf(value) + mAdapter.notifyDataSetChanged() + } + } + + private class SimpleMenuAdapter(context: Context, resource: Int) : + ArrayAdapter(context, resource) { + + var currentPosition = -1 + + override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View { + val view: View = super.getDropDownView(position, convertView, parent) + if (position == currentPosition) { + view.setBackgroundColor(context.getColorAttr(R.attr.colorMaterial100)) + } else { + view.setBackgroundColor( + ContextCompat.getColor( + context, + R.color.preference_simple_menu_background + ) + ) + } + return view + } + } +} \ No newline at end of file diff --git a/app/src/main/java/moe/matsuri/nb4a/utils/Util.kt b/app/src/main/java/moe/matsuri/nb4a/utils/Util.kt index 1a077bc..2ce8fea 100644 --- a/app/src/main/java/moe/matsuri/nb4a/utils/Util.kt +++ b/app/src/main/java/moe/matsuri/nb4a/utils/Util.kt @@ -2,13 +2,7 @@ package moe.matsuri.nb4a.utils import android.annotation.SuppressLint import android.util.Base64 -import com.google.gson.JsonDeserializationContext -import com.google.gson.JsonDeserializer -import com.google.gson.JsonElement -import com.google.gson.JsonParseException import java.io.ByteArrayOutputStream -import java.lang.reflect.Type -import java.text.NumberFormat import java.text.SimpleDateFormat import java.util.* import java.util.zip.Deflater diff --git a/app/src/main/res/layout/layout_backup.xml b/app/src/main/res/layout/layout_backup.xml index d4eb568..fb61aaf 100644 --- a/app/src/main/res/layout/layout_backup.xml +++ b/app/src/main/res/layout/layout_backup.xml @@ -1,6 +1,5 @@ + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?android:attr/selectableItemBackground" + android:paddingStart="12dp" + android:paddingEnd="12dp" + android:focusable="true"> + + diff --git a/app/src/main/res/menu/app_list_neko_menu.xml b/app/src/main/res/menu/app_list_neko_menu.xml index 0babc12..94cbd07 100644 --- a/app/src/main/res/menu/app_list_neko_menu.xml +++ b/app/src/main/res/menu/app_list_neko_menu.xml @@ -1,5 +1,4 @@ - + diff --git a/app/src/main/res/menu/traffic_menu.xml b/app/src/main/res/menu/traffic_menu.xml index 01ab078..9b5241c 100644 --- a/app/src/main/res/menu/traffic_menu.xml +++ b/app/src/main/res/menu/traffic_menu.xml @@ -1,6 +1,5 @@ - + diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 1bcc63f..c1b1a9a 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -1,4 +1,5 @@ @color/material_light_white + #303030 \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 0e33c7c..807a4b0 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -288,15 +288,6 @@ #9E9E9E #2B2B2B - - - - - - - - - - + #FAFAFA \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 25e8058..ba69cba 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -1,4 +1,4 @@ - + 264dp 88dp 8dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5907ac7..d441400 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -502,5 +502,7 @@ Anyone can write advanced plugins, which can control NekoBox. please download an Ads Bypass LAN in Core Restart APP to apply changes + Use selector + Front proxy \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 496549f..ca9afcb 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,4 +1,4 @@ - +