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 00000000..50814b49 Binary files /dev/null and b/app/src/main/res/bak/drawable-hdpi/ic_add_box_white_24dp.png differ diff --git a/app/src/main/res/bak/drawable-hdpi/ic_apps_white_36dp.png b/app/src/main/res/bak/drawable-hdpi/ic_apps_white_36dp.png new file mode 100644 index 00000000..5098d29f Binary files /dev/null and b/app/src/main/res/bak/drawable-hdpi/ic_apps_white_36dp.png differ 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 00000000..94a9bd60 Binary files /dev/null and b/app/src/main/res/bak/drawable-hdpi/ic_backup_restore_white_36dp.png differ diff --git a/app/src/main/res/bak/drawable-hdpi/ic_customization_white_36dp.png b/app/src/main/res/bak/drawable-hdpi/ic_customization_white_36dp.png new file mode 100644 index 00000000..cf8ce668 Binary files /dev/null and b/app/src/main/res/bak/drawable-hdpi/ic_customization_white_36dp.png differ 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 00000000..c6ce47d9 Binary files /dev/null and b/app/src/main/res/bak/drawable-hdpi/ic_done.png differ diff --git a/app/src/main/res/bak/drawable-hdpi/ic_general_white_36dp.png b/app/src/main/res/bak/drawable-hdpi/ic_general_white_36dp.png new file mode 100644 index 00000000..3a617247 Binary files /dev/null and b/app/src/main/res/bak/drawable-hdpi/ic_general_white_36dp.png differ diff --git a/app/src/main/res/bak/drawable-hdpi/ic_guide_white_36dp.png b/app/src/main/res/bak/drawable-hdpi/ic_guide_white_36dp.png new file mode 100644 index 00000000..d8e156be Binary files /dev/null and b/app/src/main/res/bak/drawable-hdpi/ic_guide_white_36dp.png differ 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 00000000..00f53edc Binary files /dev/null and b/app/src/main/res/bak/drawable-hdpi/ic_info_white_36dp.png differ diff --git a/app/src/main/res/bak/drawable-hdpi/ic_install_white_36.png b/app/src/main/res/bak/drawable-hdpi/ic_install_white_36.png new file mode 100644 index 00000000..0c7011ba Binary files /dev/null and b/app/src/main/res/bak/drawable-hdpi/ic_install_white_36.png differ diff --git a/app/src/main/res/bak/drawable-hdpi/ic_search.png b/app/src/main/res/bak/drawable-hdpi/ic_search.png new file mode 100644 index 00000000..407fb1be Binary files /dev/null and b/app/src/main/res/bak/drawable-hdpi/ic_search.png differ diff --git a/app/src/main/res/bak/drawable-hdpi/ic_ui_white_36dp.png b/app/src/main/res/bak/drawable-hdpi/ic_ui_white_36dp.png new file mode 100644 index 00000000..7a3362a4 Binary files /dev/null and b/app/src/main/res/bak/drawable-hdpi/ic_ui_white_36dp.png differ diff --git a/app/src/main/res/bak/drawable-mdpi/ic_add_box_white_24dp.png b/app/src/main/res/bak/drawable-mdpi/ic_add_box_white_24dp.png new file mode 100755 index 00000000..de65263c Binary files /dev/null and b/app/src/main/res/bak/drawable-mdpi/ic_add_box_white_24dp.png differ diff --git a/app/src/main/res/bak/drawable-mdpi/ic_search.png b/app/src/main/res/bak/drawable-mdpi/ic_search.png new file mode 100644 index 00000000..55c36f9c Binary files /dev/null and b/app/src/main/res/bak/drawable-mdpi/ic_search.png differ 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 00000000..97c73d81 Binary files /dev/null and b/app/src/main/res/bak/drawable-xhdpi/ic_add_box_white_24dp.png differ 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 00000000..2d270ff6 Binary files /dev/null and b/app/src/main/res/bak/drawable-xhdpi/ic_search.png differ 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 00000000..4d054c94 Binary files /dev/null and b/app/src/main/res/bak/drawable-xxhdpi/ic_add_box_white_24dp.png differ 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 00000000..d0d4d59e Binary files /dev/null and b/app/src/main/res/bak/drawable-xxhdpi/ic_search.png differ diff --git a/app/src/main/res/bak/drawable-xxhdpi/text_select_handle_left_mtrl_alpha.png b/app/src/main/res/bak/drawable-xxhdpi/text_select_handle_left_mtrl_alpha.png new file mode 100755 index 00000000..39818db8 Binary files /dev/null and b/app/src/main/res/bak/drawable-xxhdpi/text_select_handle_left_mtrl_alpha.png differ diff --git a/app/src/main/res/bak/drawable-xxhdpi/text_select_handle_right_mtrl_alpha.png b/app/src/main/res/bak/drawable-xxhdpi/text_select_handle_right_mtrl_alpha.png new file mode 100755 index 00000000..260e090b Binary files /dev/null and b/app/src/main/res/bak/drawable-xxhdpi/text_select_handle_right_mtrl_alpha.png differ 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 00000000..1f300d61 Binary files /dev/null and b/app/src/main/res/bak/drawable-xxxhdpi/ic_add_box_white_24dp.png differ diff --git a/app/src/main/res/bak/drawable/banner.png b/app/src/main/res/bak/drawable/banner.png new file mode 100644 index 00000000..43f24118 Binary files /dev/null and b/app/src/main/res/bak/drawable/banner.png differ diff --git a/app/src/main/res/bak/drawable/ic_description.xml b/app/src/main/res/bak/drawable/ic_description.xml new file mode 100644 index 00000000..420b0f44 --- /dev/null +++ b/app/src/main/res/bak/drawable/ic_description.xml @@ -0,0 +1,9 @@ + + + \ 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 00000000..fb16a443 Binary files /dev/null and b/app/src/main/res/bak/drawable/ic_tab_icon.png differ 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 00000000..6b8efe28 Binary files /dev/null and b/app/src/main/res/bak/drawable/plat_logo.png differ 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 @@ + + + + + +