From 7eb408450c929de8631afa7a0acd24fc3a02bdcd Mon Sep 17 00:00:00 2001 From: rustinmyeye Date: Thu, 8 Jan 2026 21:22:30 -0500 Subject: [PATCH] Updated app to Android 16 Updated app to android api 36 (Android 16). Builds now. Bootstrap still broken. Permission issues now. --- CODE_OF_CONDUCT.md | 64 +++++ CONTRIBUTING.md | 2 +- NeoLang/build.gradle | 22 +- NeoTermBridge/build.gradle | 15 +- NeoTermBridge/src/main/AndroidManifest.xml | 3 +- Xorg/build.gradle | 15 +- Xorg/src/main/AndroidManifest.xml | 3 +- app/build.gradle | 49 ++-- app/src/main/AndroidManifest.xml | 16 +- .../io/neoterm/component/colorscheme/comp.kt | 2 +- .../java/io/neoterm/component/config/comp.kt | 8 +- .../java/io/neoterm/component/font/comp.kt | 2 +- .../session/terminal/term-standard.kt | 2 +- .../session/view/GestureAndScaleRecognizer.kt | 4 +- .../io/neoterm/services/NeoTermService.kt | 27 +- .../main/java/io/neoterm/setup/connections.kt | 4 +- .../ui/customize/BaseCustomizeActivity.kt | 4 +- .../ui/customize/ColorSchemeActivity.kt | 13 +- .../neoterm/ui/customize/CustomizeActivity.kt | 4 +- .../java/io/neoterm/ui/customize/model.kt | 83 +++--- .../java/io/neoterm/ui/other/AboutActivity.kt | 20 +- .../java/io/neoterm/ui/other/SetupActivity.kt | 4 +- .../neoterm/ui/pm/PackageManagerActivity.kt | 40 +-- app/src/main/java/io/neoterm/ui/pm/model.kt | 68 +++-- .../ui/settings/GeneralSettingsActivity.kt | 4 +- .../io/neoterm/ui/settings/SettingActivity.kt | 4 +- .../neoterm/ui/settings/UISettingsActivity.kt | 4 +- .../io/neoterm/ui/term/NeoTermActivity.kt | 30 +- .../java/io/neoterm/utils/NeoPermission.kt | 44 ++- .../drawable-hdpi/ic_add_box_white_24dp.png | Bin 0 -> 280 bytes .../bak/drawable-hdpi/ic_apps_white_36dp.png | Bin 0 -> 92 bytes .../ic_backup_restore_white_36dp.png | Bin 0 -> 898 bytes .../ic_customization_white_36dp.png | Bin 0 -> 637 bytes .../main/res/bak/drawable-hdpi/ic_done.png | Bin 0 -> 432 bytes .../drawable-hdpi/ic_general_white_36dp.png | Bin 0 -> 500 bytes .../bak/drawable-hdpi/ic_guide_white_36dp.png | Bin 0 -> 469 bytes .../bak/drawable-hdpi/ic_info_white_36dp.png | Bin 0 -> 340 bytes .../bak/drawable-hdpi/ic_install_white_36.png | Bin 0 -> 691 bytes .../main/res/bak/drawable-hdpi/ic_search.png | Bin 0 -> 626 bytes .../bak/drawable-hdpi/ic_ui_white_36dp.png | Bin 0 -> 166 bytes .../drawable-mdpi/ic_add_box_white_24dp.png | Bin 0 -> 210 bytes .../main/res/bak/drawable-mdpi/ic_search.png | Bin 0 -> 427 bytes .../drawable-xhdpi/ic_add_box_white_24dp.png | Bin 0 -> 257 bytes .../main/res/bak/drawable-xhdpi/ic_search.png | Bin 0 -> 818 bytes .../drawable-xxhdpi/ic_add_box_white_24dp.png | Bin 0 -> 324 bytes .../res/bak/drawable-xxhdpi/ic_search.png | Bin 0 -> 1333 bytes .../text_select_handle_left_mtrl_alpha.png | Bin 0 -> 2032 bytes .../text_select_handle_right_mtrl_alpha.png | Bin 0 -> 15200 bytes .../ic_add_box_white_24dp.png | Bin 0 -> 486 bytes app/src/main/res/bak/drawable/banner.png | Bin 0 -> 6974 bytes .../main/res/bak/drawable/ic_description.xml | 9 + app/src/main/res/bak/drawable/ic_donate.xml | 9 + app/src/main/res/bak/drawable/ic_github.xml | 9 + app/src/main/res/bak/drawable/ic_info.xml | 10 + app/src/main/res/bak/drawable/ic_neoterm.xml | 43 +++ .../main/res/bak/drawable/ic_new_session.xml | 17 ++ app/src/main/res/bak/drawable/ic_person.xml | 9 + app/src/main/res/bak/drawable/ic_tab_icon.png | Bin 0 -> 187 bytes .../res/bak/drawable/ic_terminal_running.xml | 23 ++ app/src/main/res/bak/drawable/plat_logo.png | Bin 0 -> 3318 bytes .../text_select_handle_left_material.xml | 4 + .../text_select_handle_right_material.xml | 4 + .../main/res/bak/layout/dialog_edit_text.xml | 22 ++ .../res/bak/layout/dialog_edit_two_text.xml | 36 +++ app/src/main/res/bak/layout/item_color.xml | 47 ++++ .../bak/layout/item_complete_candidate.xml | 31 ++ app/src/main/res/bak/layout/item_package.xml | 30 ++ .../res/bak/layout/layout_pm_package_list.xml | 18 ++ .../res/bak/layout/popup_auto_complete.xml | 13 + app/src/main/res/bak/layout/ui_about.xml | 265 ++++++++++++++++++ .../main/res/bak/layout/ui_color_scheme.xml | 77 +++++ .../res/bak/layout/ui_command_shortcut.xml | 47 ++++ app/src/main/res/bak/layout/ui_crash.xml | 64 +++++ app/src/main/res/bak/layout/ui_customize.xml | 122 ++++++++ app/src/main/res/bak/layout/ui_faq.xml | 110 ++++++++ app/src/main/res/bak/layout/ui_main.xml | 31 ++ app/src/main/res/bak/layout/ui_pm.xml | 36 +++ .../main/res/bak/layout/ui_pm_single_tab.xml | 19 ++ app/src/main/res/bak/layout/ui_setup.xml | 145 ++++++++++ app/src/main/res/bak/layout/ui_term.xml | 26 ++ .../main/res/bak/layout/ui_term_dialog.xml | 17 ++ .../main/res/bak/layout/ui_term_embedded.xml | 16 ++ .../res/bak/layout/ui_user_script_list.xml | 46 +++ app/src/main/res/bak/layout/ui_xorg.xml | 12 + .../main/res/bak/menu/menu_color_editor.xml | 9 + app/src/main/res/bak/menu/menu_main.xml | 48 ++++ app/src/main/res/bak/menu/menu_pm.xml | 32 +++ .../main/res/bak/mipmap-hdpi/about_logo.png | Bin 0 -> 3861 bytes .../main/res/bak/mipmap-hdpi/ic_danger.png | Bin 0 -> 1952 bytes .../main/res/bak/mipmap-xhdpi/about_logo.png | Bin 0 -> 5286 bytes .../main/res/bak/mipmap-xhdpi/ic_danger.png | Bin 0 -> 1406 bytes .../main/res/bak/mipmap-xxhdpi/about_logo.png | Bin 0 -> 8502 bytes .../main/res/bak/mipmap-xxhdpi/ic_danger.png | Bin 0 -> 2223 bytes .../res/bak/mipmap-xxxhdpi/about_logo.png | Bin 0 -> 13056 bytes .../main/res/bak/mipmap-xxxhdpi/ic_danger.png | Bin 0 -> 5389 bytes .../ic_launcher_neoterm_round.png | Bin 0 -> 23831 bytes app/src/main/res/bak/raw/bell.ogg | Bin 0 -> 5090 bytes .../main/res/bak/values-zh-rCN/strings.xml | 208 ++++++++++++++ .../main/res/bak/values-zh-rTW/strings.xml | 108 +++++++ app/src/main/res/bak/values/attrs.xml | 25 ++ app/src/main/res/bak/values/colors.xml | 13 + app/src/main/res/bak/values/dimens.xml | 23 ++ .../main/res/bak/values/preference_keys.xml | 23 ++ .../main/res/bak/values/shortcut_configs.xml | 4 + app/src/main/res/bak/values/strings.xml | 237 ++++++++++++++++ app/src/main/res/bak/values/styles.xml | 50 ++++ app/src/main/res/bak/xml/app_shortcuts.xml | 14 + app/src/main/res/bak/xml/backup_config.xml | 5 + app/src/main/res/bak/xml/setting_general.xml | 58 ++++ app/src/main/res/bak/xml/settings_main.xml | 48 ++++ app/src/main/res/bak/xml/settings_ui.xml | 32 +++ app/src/main/res/values/strings.xml | 2 +- artwork/about_logo.png | Bin 51294 -> 0 bytes artwork/ic_launcher_round.png | Bin 75664 -> 0 bytes artwork/ic_tab_icon.png | Bin 4395 -> 0 bytes build.gradle | 28 +- chrome-tabs/build.gradle | 12 +- chrome-tabs/src/main/AndroidManifest.xml | 2 +- gradle.properties | 3 + nipopow-node-setup.sh | 56 ---- oldsh/1 | 1 - oldsh/alpine-ergo-node.sh | 16 -- oldsh/alpine-ergo.sh | 29 -- oldsh/ergo-startup.sh | 38 --- 124 files changed, 2637 insertions(+), 414 deletions(-) create mode 100644 CODE_OF_CONDUCT.md create mode 100755 app/src/main/res/bak/drawable-hdpi/ic_add_box_white_24dp.png create mode 100644 app/src/main/res/bak/drawable-hdpi/ic_apps_white_36dp.png create mode 100644 app/src/main/res/bak/drawable-hdpi/ic_backup_restore_white_36dp.png create mode 100644 app/src/main/res/bak/drawable-hdpi/ic_customization_white_36dp.png create mode 100644 app/src/main/res/bak/drawable-hdpi/ic_done.png create mode 100644 app/src/main/res/bak/drawable-hdpi/ic_general_white_36dp.png create mode 100644 app/src/main/res/bak/drawable-hdpi/ic_guide_white_36dp.png create mode 100644 app/src/main/res/bak/drawable-hdpi/ic_info_white_36dp.png create mode 100644 app/src/main/res/bak/drawable-hdpi/ic_install_white_36.png create mode 100644 app/src/main/res/bak/drawable-hdpi/ic_search.png create mode 100644 app/src/main/res/bak/drawable-hdpi/ic_ui_white_36dp.png create mode 100755 app/src/main/res/bak/drawable-mdpi/ic_add_box_white_24dp.png create mode 100644 app/src/main/res/bak/drawable-mdpi/ic_search.png create mode 100755 app/src/main/res/bak/drawable-xhdpi/ic_add_box_white_24dp.png create mode 100644 app/src/main/res/bak/drawable-xhdpi/ic_search.png create mode 100755 app/src/main/res/bak/drawable-xxhdpi/ic_add_box_white_24dp.png create mode 100644 app/src/main/res/bak/drawable-xxhdpi/ic_search.png create mode 100755 app/src/main/res/bak/drawable-xxhdpi/text_select_handle_left_mtrl_alpha.png create mode 100755 app/src/main/res/bak/drawable-xxhdpi/text_select_handle_right_mtrl_alpha.png create mode 100755 app/src/main/res/bak/drawable-xxxhdpi/ic_add_box_white_24dp.png create mode 100644 app/src/main/res/bak/drawable/banner.png create mode 100644 app/src/main/res/bak/drawable/ic_description.xml create mode 100644 app/src/main/res/bak/drawable/ic_donate.xml create mode 100644 app/src/main/res/bak/drawable/ic_github.xml create mode 100644 app/src/main/res/bak/drawable/ic_info.xml create mode 100644 app/src/main/res/bak/drawable/ic_neoterm.xml create mode 100644 app/src/main/res/bak/drawable/ic_new_session.xml create mode 100644 app/src/main/res/bak/drawable/ic_person.xml create mode 100644 app/src/main/res/bak/drawable/ic_tab_icon.png create mode 100755 app/src/main/res/bak/drawable/ic_terminal_running.xml create mode 100644 app/src/main/res/bak/drawable/plat_logo.png create mode 100755 app/src/main/res/bak/drawable/text_select_handle_left_material.xml create mode 100755 app/src/main/res/bak/drawable/text_select_handle_right_material.xml create mode 100644 app/src/main/res/bak/layout/dialog_edit_text.xml create mode 100644 app/src/main/res/bak/layout/dialog_edit_two_text.xml create mode 100644 app/src/main/res/bak/layout/item_color.xml create mode 100644 app/src/main/res/bak/layout/item_complete_candidate.xml create mode 100644 app/src/main/res/bak/layout/item_package.xml create mode 100644 app/src/main/res/bak/layout/layout_pm_package_list.xml create mode 100644 app/src/main/res/bak/layout/popup_auto_complete.xml create mode 100644 app/src/main/res/bak/layout/ui_about.xml create mode 100644 app/src/main/res/bak/layout/ui_color_scheme.xml create mode 100644 app/src/main/res/bak/layout/ui_command_shortcut.xml create mode 100644 app/src/main/res/bak/layout/ui_crash.xml create mode 100644 app/src/main/res/bak/layout/ui_customize.xml create mode 100644 app/src/main/res/bak/layout/ui_faq.xml create mode 100644 app/src/main/res/bak/layout/ui_main.xml create mode 100644 app/src/main/res/bak/layout/ui_pm.xml create mode 100644 app/src/main/res/bak/layout/ui_pm_single_tab.xml create mode 100644 app/src/main/res/bak/layout/ui_setup.xml create mode 100644 app/src/main/res/bak/layout/ui_term.xml create mode 100644 app/src/main/res/bak/layout/ui_term_dialog.xml create mode 100644 app/src/main/res/bak/layout/ui_term_embedded.xml create mode 100644 app/src/main/res/bak/layout/ui_user_script_list.xml create mode 100644 app/src/main/res/bak/layout/ui_xorg.xml create mode 100644 app/src/main/res/bak/menu/menu_color_editor.xml create mode 100755 app/src/main/res/bak/menu/menu_main.xml create mode 100644 app/src/main/res/bak/menu/menu_pm.xml create mode 100644 app/src/main/res/bak/mipmap-hdpi/about_logo.png create mode 100644 app/src/main/res/bak/mipmap-hdpi/ic_danger.png create mode 100644 app/src/main/res/bak/mipmap-xhdpi/about_logo.png create mode 100644 app/src/main/res/bak/mipmap-xhdpi/ic_danger.png create mode 100644 app/src/main/res/bak/mipmap-xxhdpi/about_logo.png create mode 100644 app/src/main/res/bak/mipmap-xxhdpi/ic_danger.png create mode 100644 app/src/main/res/bak/mipmap-xxxhdpi/about_logo.png create mode 100644 app/src/main/res/bak/mipmap-xxxhdpi/ic_danger.png create mode 100644 app/src/main/res/bak/mipmap-xxxhdpi/ic_launcher_neoterm_round.png create mode 100755 app/src/main/res/bak/raw/bell.ogg create mode 100644 app/src/main/res/bak/values-zh-rCN/strings.xml create mode 100644 app/src/main/res/bak/values-zh-rTW/strings.xml create mode 100644 app/src/main/res/bak/values/attrs.xml create mode 100644 app/src/main/res/bak/values/colors.xml create mode 100644 app/src/main/res/bak/values/dimens.xml create mode 100644 app/src/main/res/bak/values/preference_keys.xml create mode 100644 app/src/main/res/bak/values/shortcut_configs.xml create mode 100644 app/src/main/res/bak/values/strings.xml create mode 100644 app/src/main/res/bak/values/styles.xml create mode 100644 app/src/main/res/bak/xml/app_shortcuts.xml create mode 100644 app/src/main/res/bak/xml/backup_config.xml create mode 100644 app/src/main/res/bak/xml/setting_general.xml create mode 100644 app/src/main/res/bak/xml/settings_main.xml create mode 100644 app/src/main/res/bak/xml/settings_ui.xml delete mode 100755 artwork/about_logo.png delete mode 100755 artwork/ic_launcher_round.png delete mode 100644 artwork/ic_tab_icon.png delete mode 100644 nipopow-node-setup.sh delete mode 100644 oldsh/1 delete mode 100644 oldsh/alpine-ergo-node.sh delete mode 100644 oldsh/alpine-ergo.sh delete mode 100644 oldsh/ergo-startup.sh diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..5e5a1f39 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,64 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +Originally, NeoTerm was designed as the front end of [Termux](https://github.com/termux/termux-app) to provide some +functions that Termux didn't have, but we found it very convenient. In continuous development, we discovered our goal: +to be the best terminal for Android. In the interest of fostering an open and welcoming environment, we as contributors +and maintainers pledge to making participation in our project and our community a harassment-free experience for +everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members +* Free for forever + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take +appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, +issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the +project or its community. Examples of representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed representative at an online or offline +event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at +kiva515@foxmail.com. The project team will review and investigate all complaints, and will respond in a way that it +deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the +reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent +repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available +at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org + +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b7626729..98b26e0b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,5 +2,5 @@ # How to -This is a free software, so any contributions and any contribution types are welcomed! +NeoTerm is a free software, so any contributions and any contribution types are welcomed! diff --git a/NeoLang/build.gradle b/NeoLang/build.gradle index 1b426599..88555ae8 100644 --- a/NeoLang/build.gradle +++ b/NeoLang/build.gradle @@ -1,15 +1,22 @@ apply plugin: 'java-library' apply plugin: 'kotlin' -repositories { - mavenCentral() +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation rootProject.ext.deps["kotlin-stdlib"] } -java { - sourceCompatibility = 1.8 - targetCompatibility = 1.8 +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath rootProject.ext.deps["kotlin-gradle-plugin"] + } +} +repositories { + mavenCentral() } - compileKotlin { kotlinOptions { jvmTarget = "1.8" @@ -20,9 +27,6 @@ compileTestKotlin { jvmTarget = "1.8" } } - dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation rootProject.ext.deps["kotlin-stdlib"] testImplementation rootProject.ext.deps["junit"] } diff --git a/NeoTermBridge/build.gradle b/NeoTermBridge/build.gradle index 903106ae..b9f814d9 100644 --- a/NeoTermBridge/build.gradle +++ b/NeoTermBridge/build.gradle @@ -4,15 +4,12 @@ def libraryVersionCode = 1 def libraryVersionName = "1.0" android { - namespace "io.neoterm.bridge" compileSdkVersion rootProject.ext.android.COMPILE_SDK_VERSION defaultConfig { minSdkVersion rootProject.ext.android.MIN_SDK_VERSION targetSdkVersion rootProject.ext.android.TARGET_SDK_VERSION - versionCode libraryVersionCode - versionName libraryVersionName - testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } buildTypes { @@ -20,11 +17,17 @@ android { minifyEnabled false } } + namespace 'io.neoterm.bridge' + buildFeatures { + aidl true + } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'androidx.appcompat:appcompat:1.7.1' - androidTestImplementation('androidx.test.espresso:espresso-core:3.7.0') + implementation 'androidx.appcompat:appcompat:1.2.0' + androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', { + exclude group: 'com.android.support', module: 'support-annotations' + }) testImplementation rootProject.ext.deps["junit"] } diff --git a/NeoTermBridge/src/main/AndroidManifest.xml b/NeoTermBridge/src/main/AndroidManifest.xml index 77cf7d76..cc947c56 100644 --- a/NeoTermBridge/src/main/AndroidManifest.xml +++ b/NeoTermBridge/src/main/AndroidManifest.xml @@ -1,2 +1 @@ - + diff --git a/Xorg/build.gradle b/Xorg/build.gradle index 9ed67189..a9b4c193 100644 --- a/Xorg/build.gradle +++ b/Xorg/build.gradle @@ -1,15 +1,12 @@ apply plugin: 'com.android.library' android { - namespace "io.neoterm.xorg" compileSdkVersion rootProject.ext.android.COMPILE_SDK_VERSION defaultConfig { minSdkVersion rootProject.ext.android.MIN_SDK_VERSION targetSdkVersion rootProject.ext.android.TARGET_SDK_VERSION - versionCode 1 - versionName "1.0" - testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } buildTypes { @@ -23,16 +20,16 @@ android { jniLibs.srcDirs = ['src/main/jniLibs'] } } - lintOptions { - disable 'MissingPermission', 'MissingSuperCall', 'UnsafeDynamicallyLoadedCode' - } + namespace 'io.neoterm.xorg' } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'androidx.appcompat:appcompat:1.7.1' + implementation rootProject.ext.deps["appcompat-v7"] testImplementation rootProject.ext.deps["junit"] - androidTestImplementation('androidx.test.espresso:espresso-core:3.7.0') + androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', { + exclude group: 'com.android.support', module: 'support-annotations' + }) } diff --git a/Xorg/src/main/AndroidManifest.xml b/Xorg/src/main/AndroidManifest.xml index 99238e78..cc947c56 100644 --- a/Xorg/src/main/AndroidManifest.xml +++ b/Xorg/src/main/AndroidManifest.xml @@ -1,2 +1 @@ - + diff --git a/app/build.gradle b/app/build.gradle index a28122b5..2522d6a0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,34 +2,29 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android { - namespace "io.neoterm" - compileSdkVersion rootProject.ext.android.COMPILE_SDK_VERSION + compileSdk rootProject.ext.android.COMPILE_SDK_VERSION + ndkVersion "21.4.7075529" defaultConfig { applicationId "io.neoterm" - minSdkVersion rootProject.ext.android.MIN_SDK_VERSION - targetSdkVersion rootProject.ext.android.TARGET_SDK_VERSION + minSdk rootProject.ext.android.MIN_SDK_VERSION + targetSdk rootProject.ext.android.TARGET_SDK_VERSION versionCode 38 versionName "2.0.5" testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' - resConfigs "zh-rCN", "zh-rTW" + resourceConfigurations += ['zh-rCN', 'zh-rTW'] externalNativeBuild { cmake { cppFlags "-std=c++11" - abiFilters 'arm64-v8a' - } - } - sourceSets { - main { - jniLibs.srcDirs = ['src/main/jniLibs'] + abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86_64' } } } buildTypes { release { minifyEnabled true - zipAlignEnabled true shrinkResources true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } externalNativeBuild { @@ -37,31 +32,45 @@ android { path "CMakeLists.txt" } } - lintOptions { - abortOnError false - checkReleaseBuilds false - } compileOptions { - targetCompatibility 1.8 - sourceCompatibility 1.8 + targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { + jvmTarget = "1.8" freeCompilerArgs = ["-Xallow-result-return-type"] } + namespace 'io.neoterm' + lint { + abortOnError false + checkReleaseBuilds false + } + packagingOptions { + jniLibs { + useLegacyPackaging true + } + } } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') testImplementation rootProject.ext.deps["junit"] + androidTestImplementation project(path: ':NeoLang') implementation rootProject.ext.deps["kotlin-stdlib"] implementation 'org.greenrobot:eventbus:3.3.1' + + implementation 'androidx.recyclerview:recyclerview:1.3.2' + implementation 'androidx.recyclerview:recyclerview-selection:1.1.0' + implementation 'com.simplecityapps:recyclerview-fastscroll:2.0.1' implementation 'de.psdev.licensesdialog:licensesdialog:2.2.0' - implementation 'androidx.annotation:annotation:1.2.0' + implementation 'com.github.GrenderG:Color-O-Matic:1.1.5' + implementation 'androidx.annotation:annotation:1.7.1' implementation 'androidx.cardview:cardview:1.0.0' - implementation 'androidx.appcompat:appcompat:1.7.1' + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'androidx.appcompat:appcompat-resources:1.6.1' implementation project(':chrome-tabs') implementation project(':NeoLang') diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 095cf337..207265f0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + + + + + + @@ -138,7 +144,7 @@ + android:foregroundServiceType="specialUse" /> (NeoTermPat fun getCurrentColorSchemeName(): String { var currentColorName = - NeoPreference.loadString(R.string.key_customization_color_scheme, DefaultColorScheme.colorName) + NeoPreference.loadString(R.string.key_customization_color_scheme, DefaultColorScheme.colorName) ?: DefaultColorScheme.colorName if (!colors.containsKey(currentColorName)) { currentColorName = DefaultColorScheme.colorName NeoPreference.store(R.string.key_customization_color_scheme, DefaultColorScheme.colorName) diff --git a/app/src/main/java/io/neoterm/component/config/comp.kt b/app/src/main/java/io/neoterm/component/config/comp.kt index af7c1d38..45fee5cb 100644 --- a/app/src/main/java/io/neoterm/component/config/comp.kt +++ b/app/src/main/java/io/neoterm/component/config/comp.kt @@ -114,7 +114,7 @@ object NeoPreference { return loadInt(App.get().getString(key), defaultValue) } - fun loadString(key: Int, defaultValue: String?): String { + fun loadString(key: Int, defaultValue: String?): String? { return loadString(App.get().getString(key), defaultValue) } @@ -126,7 +126,7 @@ object NeoPreference { return preference!!.getInt(key, defaultValue) } - fun loadString(key: String?, defaultValue: String?): String { + fun loadString(key: String?, defaultValue: String?): String? { return preference!!.getString(key, defaultValue) } @@ -161,7 +161,7 @@ object NeoPreference { } fun getLoginShellName(): String { - return loadString(R.string.key_general_shell, DefaultValues.loginShell) + return loadString(R.string.key_general_shell, DefaultValues.loginShell) ?: DefaultValues.loginShell } fun getLoginShellPath(): String { @@ -216,7 +216,7 @@ object NeoPreference { return loadString( R.string.key_general_initial_command, DefaultValues.initialCommand - ) + ) ?: DefaultValues.initialCommand } fun isBellEnabled(): Boolean { diff --git a/app/src/main/java/io/neoterm/component/font/comp.kt b/app/src/main/java/io/neoterm/component/font/comp.kt index c22cf9c3..72051074 100644 --- a/app/src/main/java/io/neoterm/component/font/comp.kt +++ b/app/src/main/java/io/neoterm/component/font/comp.kt @@ -31,7 +31,7 @@ class FontComponent : NeoComponent { fun getCurrentFontName(): String { val defaultFont = DefaultValues.defaultFont - var currentFontName = NeoPreference.loadString(R.string.key_customization_font, defaultFont) + var currentFontName = NeoPreference.loadString(R.string.key_customization_font, defaultFont) ?: defaultFont if (!fonts.containsKey(currentFontName)) { currentFontName = defaultFont NeoPreference.store(R.string.key_customization_font, defaultFont) diff --git a/app/src/main/java/io/neoterm/frontend/session/terminal/term-standard.kt b/app/src/main/java/io/neoterm/frontend/session/terminal/term-standard.kt index 9fa7859b..0afaac34 100644 --- a/app/src/main/java/io/neoterm/frontend/session/terminal/term-standard.kt +++ b/app/src/main/java/io/neoterm/frontend/session/terminal/term-standard.kt @@ -305,7 +305,7 @@ class TermSessionCallback : TerminalSession.SessionChangedCallback { val termView = termSessionData?.termView if (termView != null) { val clipboard = termView.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - clipboard.primaryClip = ClipData.newPlainText("", text) + clipboard.setPrimaryClip(ClipData.newPlainText("", text)) } } diff --git a/app/src/main/java/io/neoterm/frontend/session/view/GestureAndScaleRecognizer.kt b/app/src/main/java/io/neoterm/frontend/session/view/GestureAndScaleRecognizer.kt index 0e8167d6..9c76361e 100644 --- a/app/src/main/java/io/neoterm/frontend/session/view/GestureAndScaleRecognizer.kt +++ b/app/src/main/java/io/neoterm/frontend/session/view/GestureAndScaleRecognizer.kt @@ -38,11 +38,11 @@ internal class GestureAndScaleRecognizer(context: Context, val mListener: Listen init { mGestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() { - override fun onScroll(e1: MotionEvent, e2: MotionEvent, dx: Float, dy: Float): Boolean { + override fun onScroll(e1: MotionEvent?, e2: MotionEvent, dx: Float, dy: Float): Boolean { return mListener.onScroll(e2, dx, dy) } - override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { + override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { return mListener.onFling(e2, velocityX, velocityY) } diff --git a/app/src/main/java/io/neoterm/services/NeoTermService.kt b/app/src/main/java/io/neoterm/services/NeoTermService.kt index 76ef9e6c..312624eb 100644 --- a/app/src/main/java/io/neoterm/services/NeoTermService.kt +++ b/app/src/main/java/io/neoterm/services/NeoTermService.kt @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import android.app.* import android.content.Context import android.content.Intent +import android.content.pm.ServiceInfo import android.net.wifi.WifiManager import android.os.Binder import android.os.Build @@ -40,7 +41,13 @@ class NeoTermService : Service() { override fun onCreate() { super.onCreate() createNotificationChannel() - startForeground(NOTIFICATION_ID, createNotification()) + + val notification = createNotification() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE) + } else { + startForeground(NOTIFICATION_ID, notification) + } } override fun onBind(intent: Intent): IBinder? { @@ -65,7 +72,12 @@ class NeoTermService : Service() { } override fun onDestroy() { - stopForeground(true) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + stopForeground(STOP_FOREGROUND_REMOVE) + } else { + @Suppress("DEPRECATION") + stopForeground(true) + } for (i in mTerminalSessions.indices) mTerminalSessions[i].finishIfRunning() @@ -135,7 +147,12 @@ class NeoTermService : Service() { private fun createNotification(): Notification { val notifyIntent = Intent(this, NeoTermActivity::class.java) notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - val pendingIntent = PendingIntent.getActivity(this, 0, notifyIntent, 0) + val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + PendingIntent.FLAG_IMMUTABLE + } else { + 0 + } + val pendingIntent = PendingIntent.getActivity(this, 0, notifyIntent, flags) val sessionCount = mTerminalSessions.size val xSessionCount = mXSessions.size @@ -159,7 +176,7 @@ class NeoTermService : Service() { builder.addAction( android.R.drawable.ic_delete, getString(R.string.exit), - PendingIntent.getService(this, 0, exitIntent, 0) + PendingIntent.getService(this, 0, exitIntent, flags) ) val newWakeAction = if (lockAcquired) ACTION_RELEASE_LOCK else ACTION_ACQUIRE_LOCK @@ -171,7 +188,7 @@ class NeoTermService : Service() { R.string.service_acquire_lock ) val actionIcon = if (lockAcquired) android.R.drawable.ic_lock_idle_lock else android.R.drawable.ic_lock_lock - builder.addAction(actionIcon, actionTitle, PendingIntent.getService(this, 0, toggleWakeLockIntent, 0)) + builder.addAction(actionIcon, actionTitle, PendingIntent.getService(this, 0, toggleWakeLockIntent, flags)) return builder.build() } diff --git a/app/src/main/java/io/neoterm/setup/connections.kt b/app/src/main/java/io/neoterm/setup/connections.kt index 8ba120a3..82f58d05 100644 --- a/app/src/main/java/io/neoterm/setup/connections.kt +++ b/app/src/main/java/io/neoterm/setup/connections.kt @@ -65,7 +65,7 @@ abstract class OfflineConnection : SourceConnection { private var inputStream: InputStream? = null @Throws(IOException::class) - protected abstract fun openInputStream(): InputStream + protected abstract fun openInputStream(): InputStream? @Throws(IOException::class) override fun getInputStream(): InputStream { @@ -107,7 +107,7 @@ abstract class OfflineConnection : SourceConnection { open class OfflineUriConnection(private val context: Context, private val uri: Uri) : OfflineConnection() { @Throws(IOException::class) - override fun openInputStream(): InputStream { + override fun openInputStream(): InputStream? { return context.contentResolver.openInputStream(uri) } } diff --git a/app/src/main/java/io/neoterm/ui/customize/BaseCustomizeActivity.kt b/app/src/main/java/io/neoterm/ui/customize/BaseCustomizeActivity.kt index ef60883f..d1ee91c5 100644 --- a/app/src/main/java/io/neoterm/ui/customize/BaseCustomizeActivity.kt +++ b/app/src/main/java/io/neoterm/ui/customize/BaseCustomizeActivity.kt @@ -50,8 +50,8 @@ open class BaseCustomizeActivity : AppCompatActivity() { terminalView.attachSession(session) } - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - when (item?.itemId) { + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { android.R.id.home -> finish() } return super.onOptionsItemSelected(item) diff --git a/app/src/main/java/io/neoterm/ui/customize/ColorSchemeActivity.kt b/app/src/main/java/io/neoterm/ui/customize/ColorSchemeActivity.kt index f21c9891..dfb95fe9 100644 --- a/app/src/main/java/io/neoterm/ui/customize/ColorSchemeActivity.kt +++ b/app/src/main/java/io/neoterm/ui/customize/ColorSchemeActivity.kt @@ -12,7 +12,6 @@ import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.recyclerview.widget.LinearLayoutManager -import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter import es.dmoral.coloromatic.ColorOMaticDialog import es.dmoral.coloromatic.IndicatorMode import es.dmoral.coloromatic.colormode.ColorMode @@ -29,12 +28,6 @@ import io.neoterm.utils.Terminals * @author kiva */ class ColorSchemeActivity : BaseCustomizeActivity() { - private val COMPARATOR = SortedListAdapter.ComparatorBuilder() - .setOrderForModel(ColorItem::class.java) { a, b -> - a.colorType.compareTo(b.colorType) - } - .build() - var changed = false private lateinit var editingColorScheme: NeoColorScheme lateinit var adapter: ColorItemAdapter @@ -51,7 +44,7 @@ class ColorSchemeActivity : BaseCustomizeActivity() { val terminalView = findViewById(R.id.terminal_view) Terminals.setupTerminalView(terminalView, null) - adapter = ColorItemAdapter(this, editingColorScheme, COMPARATOR, object : ColorItemAdapter.Listener { + adapter = ColorItemAdapter(this, editingColorScheme, object : ColorItemAdapter.Listener { override fun onModelClicked(model: ColorItem) { showItemEditor(model) } @@ -67,8 +60,8 @@ class ColorSchemeActivity : BaseCustomizeActivity() { return true } - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - when (item?.itemId) { + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { android.R.id.home -> finish() R.id.action_done -> applyColorScheme(editingColorScheme) } diff --git a/app/src/main/java/io/neoterm/ui/customize/CustomizeActivity.kt b/app/src/main/java/io/neoterm/ui/customize/CustomizeActivity.kt index 3733bd8e..468c8962 100644 --- a/app/src/main/java/io/neoterm/ui/customize/CustomizeActivity.kt +++ b/app/src/main/java/io/neoterm/ui/customize/CustomizeActivity.kt @@ -144,8 +144,8 @@ class CustomizeActivity : BaseCustomizeActivity() { } } - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - when (item?.itemId) { + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { android.R.id.home -> finish() } return super.onOptionsItemSelected(item) diff --git a/app/src/main/java/io/neoterm/ui/customize/model.kt b/app/src/main/java/io/neoterm/ui/customize/model.kt index f94e1754..0dbd39e5 100644 --- a/app/src/main/java/io/neoterm/ui/customize/model.kt +++ b/app/src/main/java/io/neoterm/ui/customize/model.kt @@ -5,7 +5,9 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView -import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import io.neoterm.App import io.neoterm.R @@ -15,20 +17,7 @@ import io.neoterm.component.colorscheme.NeoColorScheme /** * @author kiva */ -class ColorItem(var colorType: Int, var colorValue: String) : SortedListAdapter.ViewModel { - override fun isSameModelAs(t: T): Boolean { - if (t is ColorItem) { - return t.colorName == colorName - && t.colorValue == colorValue - && t.colorType == colorType - } - return false - } - - override fun isContentTheSameAs(t: T): Boolean { - return isSameModelAs(t) - } - +class ColorItem(var colorType: Int, var colorValue: String) { var colorName = App.get().resources .getStringArray(R.array.color_item_names)[colorType - NeoColorScheme.COLOR_TYPE_BEGIN] } @@ -39,18 +28,31 @@ class ColorItem(var colorType: Int, var colorValue: String) : SortedListAdapter. class ColorItemAdapter( context: Context, initColorScheme: NeoColorScheme, - comparator: Comparator, private val listener: ColorItemAdapter.Listener -) : SortedListAdapter(context, ColorItem::class.java, comparator), FastScrollRecyclerView.SectionedAdapter { +) : ListAdapter(DIFF_CALLBACK), + FastScrollRecyclerView.SectionedAdapter { val colorList = mutableListOf() + companion object { + private val DIFF_CALLBACK = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: ColorItem, newItem: ColorItem): Boolean { + return oldItem.colorType == newItem.colorType + } + + override fun areContentsTheSame(oldItem: ColorItem, newItem: ColorItem): Boolean { + return oldItem.colorType == newItem.colorType && + oldItem.colorValue == newItem.colorValue + } + } + } + init { (NeoColorScheme.COLOR_TYPE_BEGIN..NeoColorScheme.COLOR_TYPE_END) .forEach { colorList.add(ColorItem(it, initColorScheme.getColor(it) ?: "")) } - edit().add(colorList).commit() + submitList(colorList.toList()) } interface Listener { @@ -58,33 +60,36 @@ class ColorItemAdapter( } override fun getSectionName(position: Int): String { - return colorList[position].colorName[0].toString() + return getItem(position).colorName[0].toString() } - override fun onCreateViewHolder( - inflater: LayoutInflater, - parent: ViewGroup, - viewType: Int - ): ViewHolder { - val rootView = inflater.inflate(R.layout.item_color, parent, false) + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ColorItemViewHolder { + val rootView = LayoutInflater.from(parent.context) + .inflate(R.layout.item_color, parent, false) return ColorItemViewHolder(rootView, listener) } -} -class ColorItemViewHolder(private val rootView: View, private val listener: ColorItemAdapter.Listener) : - SortedListAdapter.ViewHolder(rootView) { - private val colorItemName: TextView = rootView.findViewById(R.id.color_item_name) - private val colorItemDesc: TextView = rootView.findViewById(R.id.color_item_description) - private val colorView: View = rootView.findViewById(R.id.color_item_view) + override fun onBindViewHolder(holder: ColorItemViewHolder, position: Int) { + holder.bind(getItem(position)) + } + + class ColorItemViewHolder( + private val rootView: View, + private val listener: Listener + ) : RecyclerView.ViewHolder(rootView) { + private val colorItemName: TextView = rootView.findViewById(R.id.color_item_name) + private val colorItemDesc: TextView = rootView.findViewById(R.id.color_item_description) + private val colorView: View = rootView.findViewById(R.id.color_item_view) - override fun performBind(item: ColorItem) { - rootView.setOnClickListener { listener.onModelClicked(item) } - colorItemName.text = item.colorName - colorItemDesc.text = item.colorValue - if (item.colorValue.isNotEmpty()) { - val color = TerminalColors.parse(item.colorValue) - colorView.setBackgroundColor(color) - colorItemDesc.setTextColor(color) + fun bind(item: ColorItem) { + rootView.setOnClickListener { listener.onModelClicked(item) } + colorItemName.text = item.colorName + colorItemDesc.text = item.colorValue + if (item.colorValue.isNotEmpty()) { + val color = TerminalColors.parse(item.colorValue) + colorView.setBackgroundColor(color) + colorItemDesc.setTextColor(color) + } } } } diff --git a/app/src/main/java/io/neoterm/ui/other/AboutActivity.kt b/app/src/main/java/io/neoterm/ui/other/AboutActivity.kt index fd6db939..f414ec35 100644 --- a/app/src/main/java/io/neoterm/ui/other/AboutActivity.kt +++ b/app/src/main/java/io/neoterm/ui/other/AboutActivity.kt @@ -77,14 +77,6 @@ class AboutActivity : AppCompatActivity() { ApacheSoftwareLicense20() ) ) - notices.addNotice( - Notice( - "ModularAdapter", - "https://wrdlbrnft.github.io/ModularAdapter", - "Copyright (c) 2017 Wrdlbrnft", - MITLicense() - ) - ) notices.addNotice( Notice( "RecyclerTabLayout", @@ -101,14 +93,6 @@ class AboutActivity : AppCompatActivity() { ApacheSoftwareLicense20() ) ) - notices.addNotice( - Notice( - "SortedListAdapter", - "https://wrdlbrnft.github.io/SortedListAdapter/", - "Copyright (c) 2017 Wrdlbrnft", - MITLicense() - ) - ) notices.addNotice( Notice( "Termux", @@ -153,8 +137,8 @@ class AboutActivity : AppCompatActivity() { startActivity(intent) } - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - when (item?.itemId) { + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { android.R.id.home -> finish() } diff --git a/app/src/main/java/io/neoterm/ui/other/SetupActivity.kt b/app/src/main/java/io/neoterm/ui/other/SetupActivity.kt index 8e032346..7981aa00 100644 --- a/app/src/main/java/io/neoterm/ui/other/SetupActivity.kt +++ b/app/src/main/java/io/neoterm/ui/other/SetupActivity.kt @@ -228,8 +228,8 @@ class SetupActivity : AppCompatActivity(), View.OnClickListener, ResultListener } } - private fun executeAptUpdate() = runApt("update", "-y") { - it.onSuccess { finish() } + private fun executeAptUpdate() = runApt("update") { + it.onSuccess { executeAptUpgrade() } } private fun executeAptUpgrade() = runApt("upgrade", "-y") { diff --git a/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt b/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt index 87546add..f8ed0c1c 100644 --- a/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt +++ b/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt @@ -14,7 +14,6 @@ import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.Toolbar import androidx.core.view.MenuItemCompat import androidx.recyclerview.widget.LinearLayoutManager -import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter import io.neoterm.R import io.neoterm.component.ComponentManager import io.neoterm.component.config.NeoPreference @@ -27,13 +26,7 @@ import java.util.* * @author kiva */ -class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListener, SortedListAdapter.Callback { - private val comparator = SortedListAdapter.ComparatorBuilder() - .setOrderForModel(PackageModel::class.java) { a, b -> - a.packageInfo.packageName!!.compareTo(b.packageInfo.packageName!!) - } - .build() - +class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListener { lateinit var recyclerView: androidx.recyclerview.widget.RecyclerView lateinit var adapter: PackageAdapter var models = listOf() @@ -47,7 +40,7 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen recyclerView = findViewById(R.id.pm_package_list) recyclerView.setHasFixedSize(true) - adapter = PackageAdapter(this, comparator, object : PackageAdapter.Listener { + adapter = PackageAdapter(this, object : PackageAdapter.Listener { override fun onModelClicked(model: PackageModel) { AlertDialog.Builder(this@PackageManagerActivity) .setTitle(model.packageInfo.packageName) @@ -59,7 +52,6 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen .show() } }) - adapter.addCallback(this) recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.adapter = adapter @@ -80,8 +72,8 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen return true } - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - when (item?.itemId) { + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { android.R.id.home -> finish() R.id.action_source -> changeSource() R.id.action_update_and_refresh -> executeAptUpdate() @@ -156,13 +148,13 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen executeAptUpdate() } - private fun executeAptUpdate() = runApt("update -y", ) { + private fun executeAptUpdate() = runApt("update") { it.onSuccess { refreshPackageList() } } - private fun executeAptUpgrade() = runApt("update -y") { update -> + private fun executeAptUpgrade() = runApt("update") { update -> update.onSuccess { - runApt("upgrade -y", "-y") { + runApt("upgrade", "-y") { it.onSuccess { Toast.makeText(this, R.string.apt_upgrade_ok, Toast.LENGTH_SHORT).show() } } } @@ -174,10 +166,12 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen pm.clearPackages() sourceFiles.forEach { pm.reloadPackages(it, false) } - models = pm.packages.values.map { PackageModel(it) }.toList() + models = pm.packages.values.map { PackageModel(it) } + .sortedBy { it.packageInfo.packageName } + .toList() this@PackageManagerActivity.runOnUiThread { - adapter.edit().replaceAll(models).commit() + adapter.submitList(models) if (models.isEmpty()) { Toast.makeText(this@PackageManagerActivity, R.string.package_list_empty, Toast.LENGTH_SHORT).show() } @@ -205,22 +199,14 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen return sortDistance(prepared, query) { it.packageName!! } .plus(sortDistance(prepared, query) { it.description!! }) .map { it.first } + .distinctBy { it.packageInfo.packageName } .toList() } override fun onQueryTextSubmit(text: String?) = false override fun onQueryTextChange(text: String?): Boolean { - text?.let { adapter.edit().replaceAll(filter(models, it)).commit() } + text?.let { adapter.submitList(filter(models, it)) } return true } - - override fun onEditStarted() { - recyclerView.animate().alpha(0.5f) - } - - override fun onEditFinished() { - recyclerView.scrollToPosition(0) - recyclerView.animate().alpha(1.0f) - } } diff --git a/app/src/main/java/io/neoterm/ui/pm/model.kt b/app/src/main/java/io/neoterm/ui/pm/model.kt index bc0b8328..faf082d0 100644 --- a/app/src/main/java/io/neoterm/ui/pm/model.kt +++ b/app/src/main/java/io/neoterm/ui/pm/model.kt @@ -5,19 +5,33 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView -import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import io.neoterm.R import io.neoterm.component.pm.NeoPackageInfo import io.neoterm.utils.formatSizeInKB class PackageAdapter( - context: Context, - comparator: Comparator, + private val context: Context, private val listener: PackageAdapter.Listener -) : SortedListAdapter(context, PackageModel::class.java, comparator), +) : ListAdapter(DIFF_CALLBACK), FastScrollRecyclerView.SectionedAdapter { + companion object { + private val DIFF_CALLBACK = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: PackageModel, newItem: PackageModel): Boolean { + return oldItem.packageInfo.packageName == newItem.packageInfo.packageName + } + + override fun areContentsTheSame(oldItem: PackageModel, newItem: PackageModel): Boolean { + return oldItem.packageInfo.packageName == newItem.packageInfo.packageName && + oldItem.packageInfo.version == newItem.packageInfo.version + } + } + } + override fun getSectionName(position: Int): String { return getItem(position).packageInfo.packageName?.substring(0, 1) ?: "#" } @@ -26,25 +40,28 @@ class PackageAdapter( fun onModelClicked(model: PackageModel) } - override fun onCreateViewHolder( - inflater: LayoutInflater, - parent: ViewGroup, - viewType: Int - ): ViewHolder { - val rootView = inflater.inflate(R.layout.item_package, parent, false) + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PackageViewHolder { + val rootView = LayoutInflater.from(parent.context) + .inflate(R.layout.item_package, parent, false) return PackageViewHolder(rootView, listener) } -} -class PackageViewHolder(private val rootView: View, private val listener: PackageAdapter.Listener) : - SortedListAdapter.ViewHolder(rootView) { - private val packageNameView: TextView = rootView.findViewById(R.id.package_item_name) - private val packageDescView: TextView = rootView.findViewById(R.id.package_item_desc) + override fun onBindViewHolder(holder: PackageViewHolder, position: Int) { + holder.bind(getItem(position)) + } + + class PackageViewHolder( + private val rootView: View, + private val listener: Listener + ) : RecyclerView.ViewHolder(rootView) { + private val packageNameView: TextView = rootView.findViewById(R.id.package_item_name) + private val packageDescView: TextView = rootView.findViewById(R.id.package_item_desc) - override fun performBind(item: PackageModel) { - rootView.setOnClickListener { listener.onModelClicked(item) } - packageNameView.text = item.packageInfo.packageName - packageDescView.text = item.packageInfo.description + fun bind(item: PackageModel) { + rootView.setOnClickListener { listener.onModelClicked(item) } + packageNameView.text = item.packageInfo.packageName + packageDescView.text = item.packageInfo.description + } } } @@ -52,18 +69,7 @@ class PackageViewHolder(private val rootView: View, private val listener: Packag * @author kiva */ -class PackageModel(val packageInfo: NeoPackageInfo) : SortedListAdapter.ViewModel { - override fun isSameModelAs(t: T): Boolean { - if (t is PackageModel) { - return t.packageInfo.packageName == packageInfo.packageName - } - return false - } - - override fun isContentTheSameAs(t: T): Boolean { - return isSameModelAs(t) - } - +class PackageModel(val packageInfo: NeoPackageInfo) { fun getPackageDetails(context: Context): String { return context.getString( R.string.package_details, diff --git a/app/src/main/java/io/neoterm/ui/settings/GeneralSettingsActivity.kt b/app/src/main/java/io/neoterm/ui/settings/GeneralSettingsActivity.kt index 0a2156db..2aa27fa1 100644 --- a/app/src/main/java/io/neoterm/ui/settings/GeneralSettingsActivity.kt +++ b/app/src/main/java/io/neoterm/ui/settings/GeneralSettingsActivity.kt @@ -50,8 +50,8 @@ class GeneralSettingsActivity : BasePreferenceActivity() { override fun onBuildHeaders(target: MutableList
?) { } - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - when (item?.itemId) { + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { android.R.id.home -> finish() } return super.onOptionsItemSelected(item) diff --git a/app/src/main/java/io/neoterm/ui/settings/SettingActivity.kt b/app/src/main/java/io/neoterm/ui/settings/SettingActivity.kt index 889052e1..7c2cc637 100644 --- a/app/src/main/java/io/neoterm/ui/settings/SettingActivity.kt +++ b/app/src/main/java/io/neoterm/ui/settings/SettingActivity.kt @@ -19,8 +19,8 @@ class SettingActivity : BasePreferenceActivity() { override fun onBuildHeaders(target: MutableList
?) { } - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - when (item?.itemId) { + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { android.R.id.home -> finish() } diff --git a/app/src/main/java/io/neoterm/ui/settings/UISettingsActivity.kt b/app/src/main/java/io/neoterm/ui/settings/UISettingsActivity.kt index d0d2c81c..a8e8e908 100644 --- a/app/src/main/java/io/neoterm/ui/settings/UISettingsActivity.kt +++ b/app/src/main/java/io/neoterm/ui/settings/UISettingsActivity.kt @@ -19,8 +19,8 @@ class UISettingsActivity : BasePreferenceActivity() { override fun onBuildHeaders(target: MutableList
?) { } - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - when (item?.itemId) { + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { android.R.id.home -> finish() } diff --git a/app/src/main/java/io/neoterm/ui/term/NeoTermActivity.kt b/app/src/main/java/io/neoterm/ui/term/NeoTermActivity.kt index acdc9cc0..6c355b19 100644 --- a/app/src/main/java/io/neoterm/ui/term/NeoTermActivity.kt +++ b/app/src/main/java/io/neoterm/ui/term/NeoTermActivity.kt @@ -4,6 +4,7 @@ import android.Manifest import android.content.* import android.content.pm.PackageManager import android.content.res.Configuration +import android.os.Build import android.os.Bundle import android.os.Handler import android.os.IBinder @@ -70,18 +71,9 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference ) } - val SDCARD_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1 - if (ContextCompat.checkSelfPermission( - this, - Manifest.permission.WRITE_EXTERNAL_STORAGE - ) != PackageManager.PERMISSION_GRANTED - ) { - ActivityCompat.requestPermissions( - this, - arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), - SDCARD_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE - ) - } + // Storage permissions are handled in NeoPermission.initAppPermission + // for older Android versions. On Android 13+, shared storage requires + // different permissions or All Files Access which we don't force here. setContentView(R.layout.ui_main) @@ -153,8 +145,8 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference return true } - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - return when (item?.itemId) { + override fun onOptionsItemSelected(item: MenuItem): Boolean { + return when (item.itemId) { R.id.menu_item_settings -> { startActivity(Intent(this, SettingActivity::class.java)) true @@ -296,15 +288,7 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection, SharedPreference override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { when (requestCode) { NeoPermission.REQUEST_APP_PERMISSION -> { - if (grantResults.isEmpty() - || grantResults[0] != PackageManager.PERMISSION_GRANTED - ) { - AlertDialog.Builder(this).setMessage(R.string.permission_denied) - .setPositiveButton(android.R.string.ok, { _: DialogInterface, _: Int -> - finish() - }) - .show() - } + // We no longer exit the app if optional permissions like notifications are denied. return } } diff --git a/app/src/main/java/io/neoterm/utils/NeoPermission.kt b/app/src/main/java/io/neoterm/utils/NeoPermission.kt index b89ccfe8..69dcbedb 100644 --- a/app/src/main/java/io/neoterm/utils/NeoPermission.kt +++ b/app/src/main/java/io/neoterm/utils/NeoPermission.kt @@ -4,6 +4,7 @@ import android.Manifest import android.content.ActivityNotFoundException import android.content.DialogInterface import android.content.pm.PackageManager +import android.os.Build import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat @@ -16,37 +17,30 @@ object NeoPermission { const val REQUEST_APP_PERMISSION = 10086 fun initAppPermission(context: AppCompatActivity, requestCode: Int) { - if (ContextCompat.checkSelfPermission( - context, - Manifest.permission.READ_EXTERNAL_STORAGE - ) - != PackageManager.PERMISSION_GRANTED - ) { + val permissions = ArrayList() + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + if (ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { + permissions.add(Manifest.permission.POST_NOTIFICATIONS) + } + } - if (ActivityCompat.shouldShowRequestPermissionRationale( - context, - Manifest.permission.READ_EXTERNAL_STORAGE - ) - ) { - AlertDialog.Builder(context).setMessage("需要存储权限来访问存储设备上的文件") - .setPositiveButton(android.R.string.ok, { _: DialogInterface, _: Int -> - doRequestPermission(context, requestCode) - }) - .show() + // On Android 13+ (API 33), READ_EXTERNAL_STORAGE is deprecated and always denied. + // We only request it for older versions. + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { + if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE) + } + } - } else { - doRequestPermission(context, requestCode) - } + if (permissions.isNotEmpty()) { + doRequestPermission(context, permissions.toTypedArray(), requestCode) } } - private fun doRequestPermission(context: AppCompatActivity, requestCode: Int) { + private fun doRequestPermission(context: AppCompatActivity, permissions: Array, requestCode: Int) { try { - ActivityCompat.requestPermissions( - context, - arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), - requestCode - ) + ActivityCompat.requestPermissions(context, permissions, requestCode) } catch (ignore: ActivityNotFoundException) { // for MIUI, we ignore it. } diff --git a/app/src/main/res/bak/drawable-hdpi/ic_add_box_white_24dp.png b/app/src/main/res/bak/drawable-hdpi/ic_add_box_white_24dp.png new file mode 100755 index 0000000000000000000000000000000000000000..50814b496e8d3d6bfdaabb374d0b98f02d20d160 GIT binary patch literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K;Lb6AYF9SoB8UsT^3j@P1pisjL z28L1t28LG&3=CE?7#PG0=Ijcz0ZK3>dAqwX{BQ3+vmeOgEbxddW?`VBp6OsFEs^HOeH~n!3+##lh0ZJd7_>!jv*C{ m$qH-+^?yFH+k2+RwlFdXcbEjO>-^IL(&p*v=d#Wzp$Py{>J~Zx literal 0 HcmV?d00001 diff --git a/app/src/main/res/bak/drawable-hdpi/ic_backup_restore_white_36dp.png b/app/src/main/res/bak/drawable-hdpi/ic_backup_restore_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..94a9bd60f4fddc09b857659c03f1eff95f05fcf8 GIT binary patch literal 898 zcmV-|1AY97P)6K@$h5EQ~FGY3kJ z`U8pvYJy6Xm;?nH_WFLsO-8!O@Nf%ITSf+s zknI`36Tm&deZb$qdEgxIy`)QR&a3!+0kR$PYk?PmWx#DUPX7YF1-=CKN^)0lodMZ? z8rTUu+|_u>{RnK56aZVP6Cm3gfZf29lEt5apMYP15nvAR5HPPK_iuvQ)rP1QknMMY zv4WwfjSqm&CH+z5!1mq1%fLH8)LM_mB#kzKY6N8aCE$yKf$xCl>wuIUC9ng)k^*my zql0KdkA=?p=h)ff0leDEMV0$Z2PS3ccw;KQ*1Xi}DtOe90 zFkvu@I`-AZbg)}eW3+9@B7Pv{mr44jwuWjzRf6f5;t688j(RJjbK4iwcf-JBL_Yy~ zL$=#sOvP(mR<4;rqSDi`y#R;-+w1J^t790)Rl2rs&*eHl`9~$iJwAzA542&y<@xa$ z5VuuOoF9uNofsOB?fAlxuDk7q9%yCswqvIq1@6k#5<~KrniR#ZT2pbtzTY+$I;AWx zfYW)zU$0Z(ED-;n$#+@Zksr^Xjgp2x@(W!OS3oSn*?rbkbk?io0a$0FQ-lhjrUA?I zJ`R9))EJIaHzsg=z<={ltf;AYqdf{d2;86ZC7wn9-&4BJR1GBFSIP$R(5KQZKy3lL Y3V%r^Gz;{vmjD0&07*qoM6N<$f5GznB5GznR&T9DM~)gc*6IsyYGi7~G|`j&e|0ponE4BAq*`O1N96bSfeb9>4+r z^eo5+I8Q+(fn3bINBqtwWG1basxojHoICe2a zSFYR_EV^k9fHB0l^Ch7#idLeI&WZxXTonP^^shG&8I+C`Q0RtK*3zVEXp54XGiO^vK3u4-He Xh@|Ev$Fb7G00000NkvXXu0mjfhL{v3 literal 0 HcmV?d00001 diff --git a/app/src/main/res/bak/drawable-hdpi/ic_done.png b/app/src/main/res/bak/drawable-hdpi/ic_done.png new file mode 100644 index 0000000000000000000000000000000000000000..c6ce47d973f5b53ddab4163684da0739ff4bc81c GIT binary patch literal 432 zcmV;h0Z;ykP)kF1%wWu0!RmR03Bpf0igm)ASFNtDIrvFnVXR^jv`q z=hf*XVqzC3=D`e#&B&b4q!SX61<6Afd9^7Mkyij~0QV&K7IhVn!F(FTFMvmzRCADn zvB7+i)Wq8Mp#bI&z_NKlDVSynrDB?Zaxm3F0nERt8C_i$SG84Ef~l5JDW(c&2*wK% zkvjl;caMo}ih5r}o&bD1&-T`g``)t}GMFC#JCe^S2>VQD?4mO+3v-r`=Y?C6s}$5& z7#H*b;N1a4QDb5*YDh%30A3u_hUA+ssj)GkqV}OyB=!H(RRa@T_9C(a@Zh9!Le;|b zfpn!P>efX8(3Y<&anNcCEtcTcq37KIO3%PmFwsukgR&o(-DhHLB)YkpdeP~-8Pb7c z5PLrgGFyUfCtcL&$z*{Xl>XE+u=hNZnnZR{2O8lLz@Zi0LSqk>0RogRwu#ad=0?|5K+;hSQlM=fKD!QL+`Q((n_1fSeH_SEPa9ygop|; z>O*J}T8G@yD)%+=_qcy*F8O!v=OdjyoMD+dpIFrxt9)dOyDaJ?xJZqk7@@`pF%DQ` zNp5(|0l83Pgye=i)I9h!m=tP^kV$ns6~ku_TgqqdX^i{yNU=5XRD@ULMnqI)A)rP= zZcEegh+K<`rXZkAZbkp&0{dik@KgYww`2yK({V&(T6mfPk2aZ5lUQUQV?;%B5RhOD zDa*zkGHY@`jm%Bi*u+Sw$N>Q<#=2~L!05^mUobkdF~n%d5!)Dj**L<8bQ78N%OEmpIN@MEH^9>GGv+`JmaiR q0-sxK(4o&Ezv$CpgB$odef|I#@$;4zVspm;00005qWP;SgA4yK@Uvve!0`S%&khhwU zoQFM209pYUll(GN2|(sBjGANOmfNBp^vQ0L~Lnx?%kQ znxD6A^BRmW3M6TW@zBicy0P!=J!^Gs!8qw-DtxBsiHtn0R9bX zK#;I?J5W``F9(3Ar-&-lm*J(JD+=U7c9EsFdurmg=XL{C4(x(9)Jbl(g!nj61!Yql zx}H48Mo}LMr;>CJz+frsvhmPIB*8rbOHC*+BayZj1W`7x1MesUo8D00000 LNkvXXu0mjfi1pF{ literal 0 HcmV?d00001 diff --git a/app/src/main/res/bak/drawable-hdpi/ic_info_white_36dp.png b/app/src/main/res/bak/drawable-hdpi/ic_info_white_36dp.png new file mode 100644 index 0000000000000000000000000000000000000000..00f53edce0e5c5ba3b36ecee05fc6ec8c172cdc2 GIT binary patch literal 340 zcmV-a0jvIrP) z{qOx%>h;7s8wx56Jw1ks6KiI1kPi+#aH&PJ2*rG2kW`aBhfKK;qJpW6`6g6X0Tp+Kkgf)>vOxu@%56}U z3@UAqNxoWRgL?0avf0r66UZcknozT!fd*!ul0iosv`z*shZSj)K!&$r+jJ6WH*Wue zIy#Vd=B|yDMb~5N+mUhA&86jk4aR&ik^dv-u+xZ`Kd)*La`$@UnBd-%E5pt?DFHTP mMNUaWM@K`+k>x0Uub?07ICz#IlqDzt0000hyWygtdkz1^F+ zAJL!8W!Lhzvh*aw4$N?1Jaz}vJCUs-MDm%LJ+7R60dVVWK=P59y{Mku0JvNXMDl}~ zy>=X(0JsW(o|@S==h;U9Z(2~z2#sI*GjOmAkX#)_k=4Tngc+O1N1qV|CV2Q3AR};T{=Dg|pNV{eBC;J@=lr=s8IpztSL?bgcY6 z{C@+eQR+8lrmva>MN+vYO{$}%{U6l+JfJf(dl!7QU<4(&u8|akV4?yz2cZ43c|a0E zNq=O5(($=fk`|3s`o009S8o9vg+QHBuK~{hoO{$H1=39VV%;f#uj%(BLL?R5W;s^? zawJU|@@mW%CGYd@dH#Rl3c$$*(0Ja`p1G!cIvp2XG_5q!)}j_8%K<2Xl*s9ZA)(U(_ujPvoc7WMA_-|8 zL+W1EnuAy1a9vF1^BO3;_Uwzs%qG_&Zyr)EdDGoKnAGVfx8JSq_WK}-eBJ@|qJ3}? Z`UlN~_9elHZ(INX002ovPDHLkV1lFdKacOFc$-0q4w=sUQZh@eNs1>C@c2hpG=?-c)n3XDaM ziIeG0M!Mi5!(^tqtNZWns&O1^)~s0zo#pfSTF?&?-~c>=H|Bxw#X&EqskY9KgA~Yu zToLG*Loiwm9glz{_$r~}5_)F?)K{wW?clUXCqJ0qo=Jn&N{sxehdfB@v!DlbFmyc+ zjyz;W@{5=ZAgSoYHJJEqfzp2<3T_qeubb-pq(bw@e~|&pFRhrp5ffYGiD>xBkA_)V zH^SGE)-4v!2Ze^|daMk8QN_;Gr!#<6(co^mBgXP``;6-hASD``4#4M}@Ohv!fM?NI zcK|+ngwH!#Yq|pXbTyO-;s7EaVpn_7b~^uu0G`DTq(egYIwh3Wu!v_(E@HWj?gX%n z9txicodFCh4xW)R{Edr)k^BwlP9&@fIW|b=AEC37%TYEP$xJG zprp*WeqTY%WDt#D%SS<9n5`rqWFO*w%yf+$<=rV;;@60iLLI?_kWoArGy46A>s>l0 z*7(GJVoAL6HKpP!V94Dues5V3eAajnBA_~6l#yb&jVlP1%wkSh%wr~U6`ctmGORv1 z`3%C!sjB4^mRV5Ai2_)3!ep+QAQqgk8PCL0=tf=!;aIa~%~~kz8wsa)QfSw-HUIzs M07*qoM6N<$f)ctP|k0wldT1B8K8uBVG*h{y5d1c`eO_P_mK{Qv(y zb@o5ZueLNwD*yg}y58%+^#4Wz&7b}UbA3`|Gi|WsO=0EQbT6>kjaSMvdvc zyP~|f|NH-6n#i~1XZ^G@uU@?WZ~T942PdO=~G=WkM1 z<>}%WVsSe8$9V^-lm)Zf4*b{u|Co9Gzu$|q4y>19iCdJVz!nhBthaID0>!9aWp z$s!PY84&ja@oXSIjOLI&AZDee&yg*!Mh|KrpB;$9fcOBCx+-c|4l;NvlA!?v)GGk- zE+q9vlsX`gR38D=St99~M5zNNBgMHW3Hs(i^_>J_Zb}@m8*0#E67?k^g@OSk4uB=T z9uoC=BRRmH5(mJt*9;Q%g&{e>f)WQTff{m7oK(jx}MN1=LF zQ<@8;fcON|uzf%*OF%s{5KlvLbQm=XBjiv3RX`?qe2#4SGO85EKtotS1qxbOKMRQC zfY<|wLx8v$h>xJDsQ_X#YF5Mb1ZqMUUJk@HNc<#f){17(U_OP#;&nhA4hnW?1$Kre zj(|FZ4~UI{*a?WOfmj-gnsk~vf=GvsI%3c|0@RQd87N19EY}{$ro9-$C>RAe0036j V^0DEMkhTB-002ovPDHLkV1l;_qw@d& literal 0 HcmV?d00001 diff --git a/app/src/main/res/bak/drawable-xhdpi/ic_add_box_white_24dp.png b/app/src/main/res/bak/drawable-xhdpi/ic_add_box_white_24dp.png new file mode 100755 index 0000000000000000000000000000000000000000..97c73d811e6b55da6fcb370a7742fdda7e14a76a GIT binary patch literal 257 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}a}tg=CK)Uj~LMH3o);76yi2K%s^g z3=E|}g|8AA7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+;1OBOz`!jG!i)^F=12eq zD?MEtLn02pz3$C*K!Jzl!klFl)%NVdf!{B0mdKI;Vst0J@x15dZ)H literal 0 HcmV?d00001 diff --git a/app/src/main/res/bak/drawable-xhdpi/ic_search.png b/app/src/main/res/bak/drawable-xhdpi/ic_search.png new file mode 100644 index 0000000000000000000000000000000000000000..2d270ff61355954a81e1d84da26fb0d9104d17df GIT binary patch literal 818 zcmV-21I_%2P)FbngrEGdi4vuhM!G~MCZQ(3Y(r}rQsyS@2W5@8vLB{JOKI{YQ;RZ7 zm-)8;>3To)sN3oDoO92;=i~Fa&hym!m+kKP^4jO~IiK@9Hwe_!)YR0})YMY2QmM2U z+5=sNMxpo67ibQefnGwxP#3i2e=2-EbRGH(%_q<#bdtc;YvIk%0Q4ha;bBcf2kNc( zR_I-gg@<*Apw>h2`*>f^ThI$=wa>-xhknHrL2wFCA9NZz3Z3V3VzL4VZ=sbw7T*^0 zpQls5BW@Yv_Zy(A(Dw*m6J8yTNM;!{B_vBLq9_d@DsoUVax{rgFY=|`rE%52^`$kLFQoJJq@K#pXk`JJ#FbKDR!?+SovKjtjQd}xR{6 zxB^fxB=gK-yiLNkJLC#Lw;`F|wwf03drkn*;tIevA)!kaVlCokNI2FTmsjBi;T$NY zy$ay(lmPpJ>$gE^Sr*c|qx0UMHN>Ef^BUIxsQvv(fH08K_4l>l|AsFep^k{wRleF+ zWBlDl=#}7i#+&9Sp9K#hAUuV(Ch)fq>WrBtGH?p2)E9g1s^m0&|T;@7fgfF%>*sR&&9fhkRnWlpb!*-LQn__K_OHHA(v$c^u42|APZ)I wke%WU5VBW%8H8h*EnZDcO-)TrO|2UH1L;IKyG5`Po07*qoM6N<$f=CdBwEzGB literal 0 HcmV?d00001 diff --git a/app/src/main/res/bak/drawable-xxhdpi/ic_add_box_white_24dp.png b/app/src/main/res/bak/drawable-xxhdpi/ic_add_box_white_24dp.png new file mode 100755 index 0000000000000000000000000000000000000000..4d054c94730d5934e6f06fc49f26084cab9c5df6 GIT binary patch literal 324 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhaw6p}rHd>I(3)EF2VS{N990fib~ zFff!FFfhDIU|_JC!N4G1FlSew4N!t9$=lt9;eUJonf*W>XMsm#F#`j)FbFd;%$g$s z6x`$K;uw-~@9j-Tu0sYQEf3fDoL}&zL-m!eulA)^zEdvUt!UJXn_$EA@AJ2Z$}J8? zjtkdvHZU+UUD43cdbw9j_I4Xe0yybfZE@l5x0$2@h)#xxe4?KgQu&X J%Q~loCIF~!Zt?&C literal 0 HcmV?d00001 diff --git a/app/src/main/res/bak/drawable-xxhdpi/ic_search.png b/app/src/main/res/bak/drawable-xxhdpi/ic_search.png new file mode 100644 index 0000000000000000000000000000000000000000..d0d4d59ed3b71db105a1f55dbc8a9993ac1af1f3 GIT binary patch literal 1333 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 PyaQ{ksJ0B68@K)!N!r*i literal 0 HcmV?d00001 diff --git a/app/src/main/res/bak/drawable-xxxhdpi/ic_add_box_white_24dp.png b/app/src/main/res/bak/drawable-xxxhdpi/ic_add_box_white_24dp.png new file mode 100755 index 0000000000000000000000000000000000000000..1f300d61985fbeb0e4199af0e013ca32738384ec GIT binary patch literal 486 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 + + \ No newline at end of file diff --git a/app/src/main/res/bak/drawable/ic_donate.xml b/app/src/main/res/bak/drawable/ic_donate.xml new file mode 100644 index 00000000..26d0c344 --- /dev/null +++ b/app/src/main/res/bak/drawable/ic_donate.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/bak/drawable/ic_github.xml b/app/src/main/res/bak/drawable/ic_github.xml new file mode 100644 index 00000000..c53efbb9 --- /dev/null +++ b/app/src/main/res/bak/drawable/ic_github.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/bak/drawable/ic_info.xml b/app/src/main/res/bak/drawable/ic_info.xml new file mode 100644 index 00000000..3a075bdc --- /dev/null +++ b/app/src/main/res/bak/drawable/ic_info.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/bak/drawable/ic_neoterm.xml b/app/src/main/res/bak/drawable/ic_neoterm.xml new file mode 100644 index 00000000..9f2bc7e1 --- /dev/null +++ b/app/src/main/res/bak/drawable/ic_neoterm.xml @@ -0,0 +1,43 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/bak/drawable/ic_new_session.xml b/app/src/main/res/bak/drawable/ic_new_session.xml new file mode 100644 index 00000000..3f640423 --- /dev/null +++ b/app/src/main/res/bak/drawable/ic_new_session.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/bak/drawable/ic_person.xml b/app/src/main/res/bak/drawable/ic_person.xml new file mode 100644 index 00000000..a3b0459d --- /dev/null +++ b/app/src/main/res/bak/drawable/ic_person.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/bak/drawable/ic_tab_icon.png b/app/src/main/res/bak/drawable/ic_tab_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fb16a4438a806f82029febfb550628dcfd6cfc9c GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`O`a}}Ar}5;Ctu`jFyLWbFKpSg zqfvUrt&;Pzopr0LiyPR{#J2 literal 0 HcmV?d00001 diff --git a/app/src/main/res/bak/drawable/ic_terminal_running.xml b/app/src/main/res/bak/drawable/ic_terminal_running.xml new file mode 100755 index 00000000..4e28fd19 --- /dev/null +++ b/app/src/main/res/bak/drawable/ic_terminal_running.xml @@ -0,0 +1,23 @@ + + + + + + + diff --git a/app/src/main/res/bak/drawable/plat_logo.png b/app/src/main/res/bak/drawable/plat_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6b8efe28dd5f926e0789e8526c9271be9000c4c9 GIT binary patch literal 3318 zcmeHJ`CAg$8a|k%WwwnuWf}E|T8_&orkM*(P7xVuE{O}ugj!~)iIN*gHIq(Sl$GWJ zKHU^kbKlC9%5p)az-3%e8&eZSOhgnxFLv)=G54PH!*_mozxO=v_r2e9&Y#YXNcAmR zTL1v+s58I10HCBeDgo6^im(vXEd^j}1M1gb+@i7sJi+;WZJL`#`)Wdza+r74_o(_W z+aMMQ(!Fw z?Q~=6-KOIQ-faO-ArNK^W+z~-Z3ew#=7Qtb!4B{;`85Ero#5p?LjX|9AQ+|wC;<0| zqmC-T*g}}cu`sLj+8y8=5|ldXd-nQJk|tZ&uuc_fVTaDE{!|Il&REF)kxi@ZaHy`7 zma$M|8W%aq%_+hUPLd;Py6hV~s5Ox{`Yydj&5LQ}e(G+4$3oEDAxoa@YQ{uPP=*E+ zL98F4+71`a9}CTx2u={y#gnOaEOY5z(qIV5%-W*Nt`k5xKepC@VCS0c|=8*e(y23AK&OkM;nRvnk(QdaB zYJAy=icVPML5JP%?7OGUIV=c&Nc>`!lTf*^O<~DuD~1BD+;rqv{ETIb35(M*C@1yXxb}iEm)_#sVx#9! z2;J?GA4#MxH_Xc5{?F!DTjds2Qt7ajZ4Oc83=)|1hZv6_ks2)(Z$ zhR`1x^gOXQ=N?q=j5e^5SXA91Jd*Fr6m{EWliKUVx>Xv}86gvu>rB@UijKW0^NVfI zzMa6&eOzR+ERXGv^i`rfRLsY-aJkW56SYz{|2D~*%X%wvDvvL9JtA~nG!gcub!)Ba z&iMEB?3zY;jF`!eu9AEv+0s`|xbQTD%7Fx#@ty|&r(NJl;UBIkl39LOc2NemS`Id3^7UWC$*ujRb&-ebe z|6G-qpU3%0JEZS4p^%eL8;?pmXH-UxINz`UPc^>TbHT4^<0d_TN#oz89FibQ?)yq; z*W+5Jf1-W$)#az(A+-Y;-oKq29z@>tp_n(EaTke#^7ri~xiR7P&^iG@f|~a3ls@&3Ui8 z*!0$m&Ht>0_0hz{TWRRqZpVn@vg5FE* zh9|1He1f_BVWSeIk!3CZ8e!n@5}NQ8pDN!`>wEvJ4*Xr>s&ypfX>;Ti+R7;@ddl6p zs4Rrc^#C6wu;Q~iG0CwI!!q*zi^W0n#Wcy#1ibY2R_1YcC;{I()|_Oac-D6AsJx_XWO(#)Hc!1NcQM`P%Ut&YDkbx+h;BAg*Cr15 zFQ@k%g-v*|qvmp+R19l#Pl2-IOUnH=`0-4?eRQ1Cs~UY4^FyAl_eDA7{Z25K%1^9G z;>X<IeuCi;rQ-~oc{`C3tK&vwjy2oUa7XyygWZ3L}X zv+H(+aEQ$aj^DdgUGZ+nNX1Ibs^>sgVT^Cj81%Mo?{ZGQOx|Qfv&t=u&da>B_TdU@jBqnf45{6tCH6JpqNWc z?fEpg=p}HQ<&ceg%(83|wU3uA#&{*aeFvNRgQZsc53eU=0Xbs}8U={svzIc^#K0J`dy34V8(2sLo^MGzw}oyuO`U4 zr-{>WvniIG-N;&b@FhEW@Uzhy4qv4s15oaomLNi{o8q~C_VF~L^77PjXtwo~EyGBN zu&o!`56r9c+Kl?w!M%C;YRum<80odDc&oOO&A2DLe&3MC@Sf(^g7R{--SE)l_#Mk0 uo^Xk`Yg$FPw17%e{%8H%{uk63cCCQ{?Eu|o+|7V>y{J=;zZRdw-TF85N#Ilf literal 0 HcmV?d00001 diff --git a/app/src/main/res/bak/drawable/text_select_handle_left_material.xml b/app/src/main/res/bak/drawable/text_select_handle_left_material.xml new file mode 100755 index 00000000..7e447c22 --- /dev/null +++ b/app/src/main/res/bak/drawable/text_select_handle_left_material.xml @@ -0,0 +1,4 @@ + + diff --git a/app/src/main/res/bak/drawable/text_select_handle_right_material.xml b/app/src/main/res/bak/drawable/text_select_handle_right_material.xml new file mode 100755 index 00000000..1d1e65b0 --- /dev/null +++ b/app/src/main/res/bak/drawable/text_select_handle_right_material.xml @@ -0,0 +1,4 @@ + + diff --git a/app/src/main/res/bak/layout/dialog_edit_text.xml b/app/src/main/res/bak/layout/dialog_edit_text.xml new file mode 100644 index 00000000..4fa8d000 --- /dev/null +++ b/app/src/main/res/bak/layout/dialog_edit_text.xml @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/bak/layout/dialog_edit_two_text.xml b/app/src/main/res/bak/layout/dialog_edit_two_text.xml new file mode 100644 index 00000000..714ab12a --- /dev/null +++ b/app/src/main/res/bak/layout/dialog_edit_two_text.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/bak/layout/item_color.xml b/app/src/main/res/bak/layout/item_color.xml new file mode 100644 index 00000000..4a65ffee --- /dev/null +++ b/app/src/main/res/bak/layout/item_color.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/bak/layout/item_complete_candidate.xml b/app/src/main/res/bak/layout/item_complete_candidate.xml new file mode 100644 index 00000000..5419fab9 --- /dev/null +++ b/app/src/main/res/bak/layout/item_complete_candidate.xml @@ -0,0 +1,31 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/bak/layout/item_package.xml b/app/src/main/res/bak/layout/item_package.xml new file mode 100644 index 00000000..b5fa57eb --- /dev/null +++ b/app/src/main/res/bak/layout/item_package.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/bak/layout/layout_pm_package_list.xml b/app/src/main/res/bak/layout/layout_pm_package_list.xml new file mode 100644 index 00000000..e9a0fadb --- /dev/null +++ b/app/src/main/res/bak/layout/layout_pm_package_list.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/bak/layout/popup_auto_complete.xml b/app/src/main/res/bak/layout/popup_auto_complete.xml new file mode 100644 index 00000000..0d0e5947 --- /dev/null +++ b/app/src/main/res/bak/layout/popup_auto_complete.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/bak/layout/ui_about.xml b/app/src/main/res/bak/layout/ui_about.xml new file mode 100644 index 00000000..b9c69d6c --- /dev/null +++ b/app/src/main/res/bak/layout/ui_about.xml @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/bak/layout/ui_color_scheme.xml b/app/src/main/res/bak/layout/ui_color_scheme.xml new file mode 100644 index 00000000..bb2c600d --- /dev/null +++ b/app/src/main/res/bak/layout/ui_color_scheme.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/bak/layout/ui_command_shortcut.xml b/app/src/main/res/bak/layout/ui_command_shortcut.xml new file mode 100644 index 00000000..43c76782 --- /dev/null +++ b/app/src/main/res/bak/layout/ui_command_shortcut.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/bak/layout/ui_crash.xml b/app/src/main/res/bak/layout/ui_crash.xml new file mode 100644 index 00000000..2c4950f1 --- /dev/null +++ b/app/src/main/res/bak/layout/ui_crash.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/bak/layout/ui_customize.xml b/app/src/main/res/bak/layout/ui_customize.xml new file mode 100644 index 00000000..dfd275bd --- /dev/null +++ b/app/src/main/res/bak/layout/ui_customize.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/bak/layout/ui_faq.xml b/app/src/main/res/bak/layout/ui_faq.xml new file mode 100644 index 00000000..c4fd8408 --- /dev/null +++ b/app/src/main/res/bak/layout/ui_faq.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/bak/layout/ui_main.xml b/app/src/main/res/bak/layout/ui_main.xml new file mode 100644 index 00000000..61f5ea5f --- /dev/null +++ b/app/src/main/res/bak/layout/ui_main.xml @@ -0,0 +1,31 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/bak/layout/ui_pm.xml b/app/src/main/res/bak/layout/ui_pm.xml new file mode 100644 index 00000000..a9b83b7e --- /dev/null +++ b/app/src/main/res/bak/layout/ui_pm.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/bak/layout/ui_pm_single_tab.xml b/app/src/main/res/bak/layout/ui_pm_single_tab.xml new file mode 100644 index 00000000..ceca52d3 --- /dev/null +++ b/app/src/main/res/bak/layout/ui_pm_single_tab.xml @@ -0,0 +1,19 @@ + + + + + + + + diff --git a/app/src/main/res/bak/layout/ui_setup.xml b/app/src/main/res/bak/layout/ui_setup.xml new file mode 100644 index 00000000..ec2de0fd --- /dev/null +++ b/app/src/main/res/bak/layout/ui_setup.xml @@ -0,0 +1,145 @@ + + + + + +