From 59177b1bec8387987615c82b73638754eee59ca7 Mon Sep 17 00:00:00 2001 From: FunkyMuse Date: Mon, 24 Jul 2023 15:37:03 +0200 Subject: [PATCH] start migrating to ViewBinding --- build.gradle | 38 -- build.gradle.kts | 16 + commons/build.gradle | 57 --- commons/build.gradle.kts | 93 +++++ .../commons/activities/AboutActivity.kt | 341 ++++++++++-------- .../activities/ContributorsActivity.kt | 38 +- .../activities/CustomizationActivity.kt | 3 + .../commons/extensions/Binding.kt | 11 + .../BottomActionMenuItemPopup.kt | 14 +- gradle/libs.versions.toml | 143 ++++++++ gradle/wrapper/gradle-wrapper.properties | 2 +- jitpack.yml | 3 +- samples/build.gradle | 34 -- samples/build.gradle.kts | 39 ++ settings.gradle | 1 - settings.gradle.kts | 17 + 16 files changed, 537 insertions(+), 313 deletions(-) delete mode 100644 build.gradle create mode 100644 build.gradle.kts delete mode 100644 commons/build.gradle create mode 100644 commons/build.gradle.kts create mode 100644 commons/src/main/kotlin/com/simplemobiletools/commons/extensions/Binding.kt create mode 100644 gradle/libs.versions.toml delete mode 100644 samples/build.gradle create mode 100644 samples/build.gradle.kts delete mode 100644 settings.gradle create mode 100644 settings.gradle.kts diff --git a/build.gradle b/build.gradle deleted file mode 100644 index f9f8930ae..000000000 --- a/build.gradle +++ /dev/null @@ -1,38 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - ext { - propCompileSdkVersion = 33 - propMinSdkVersion = 23 - propTargetSdkVersion = propCompileSdkVersion - propVersionCode = 1 - propVersionName = '5.34.26' - kotlin_version = '1.7.10' - } - - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.3.1' - classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - google() - mavenCentral() - maven { url 'https://jitpack.io' } - } -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 000000000..57caeb28e --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + alias(libs.plugins.android).apply(false) + alias(libs.plugins.kotlinAndroid).apply(false) + alias(libs.plugins.ksp).apply(false) + alias(libs.plugins.kapt).apply(false) + alias(libs.plugins.parcelize).apply(false) + alias(libs.plugins.kotlinAndroidExtensions).apply(false) + alias(libs.plugins.library).apply(false) + alias(libs.plugins.kotlinSerialization).apply(false) +} + +tasks.register("clean") { + delete { + rootProject.buildDir + } +} diff --git a/commons/build.gradle b/commons/build.gradle deleted file mode 100644 index 97770f037..000000000 --- a/commons/build.gradle +++ /dev/null @@ -1,57 +0,0 @@ -plugins { - id "com.android.library" - id "kotlin-android" - id "kotlin-android-extensions" - id "kotlin-kapt" - id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlin_version" -} - -android { - compileSdkVersion propCompileSdkVersion - - defaultConfig { - minSdkVersion propMinSdkVersion - targetSdkVersion propTargetSdkVersion - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" - consumerProguardFiles "proguard-rules.pro" - } - } - - sourceSets { - main.java.srcDirs += "src/main/kotlin" - } -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1" - implementation "androidx.constraintlayout:constraintlayout:2.1.4" - implementation "androidx.documentfile:documentfile:1.0.1" - implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" - implementation "androidx.exifinterface:exifinterface:1.3.6" - implementation "androidx.biometric:biometric-ktx:1.2.0-alpha05" - implementation "com.googlecode.ez-vcard:ez-vcard:0.11.3" - - api "joda-time:joda-time:2.11.0" - api "com.github.tibbi:RecyclerView-FastScroller:5a95285b1f" - api "com.github.tibbi:reprint:2cb206415d" - api "com.github.duolingo:rtl-viewpager:940f12724f" - api "com.github.aritraroy:PatternLockView:a90b0d4bf0" - api "androidx.core:core-ktx:1.8.0" - api "androidx.appcompat:appcompat:1.6.1" - api "com.google.android.material:material:1.9.0" - api "com.google.code.gson:gson:2.9.1" - - api "com.github.bumptech.glide:glide:4.15.1" - kapt "com.github.bumptech.glide:compiler:4.15.1" - annotationProcessor "com.github.bumptech.glide:compiler:4.15.1" - - api "androidx.room:room-runtime:2.5.2" - kapt "androidx.room:room-compiler:2.5.2" - annotationProcessor "androidx.room:room-compiler:2.5.2" -} diff --git a/commons/build.gradle.kts b/commons/build.gradle.kts new file mode 100644 index 000000000..14e5e8645 --- /dev/null +++ b/commons/build.gradle.kts @@ -0,0 +1,93 @@ +plugins { + alias(libs.plugins.library) + alias(libs.plugins.kotlinAndroid) + alias(libs.plugins.kapt) + alias(libs.plugins.kotlinSerialization) + alias(libs.plugins.kotlinAndroidExtensions) + `maven-publish` +} + +android { + compileSdk = libs.versions.app.build.compileSDKVersion.get().toInt() + + defaultConfig { + minSdk = libs.versions.app.build.minimumSDK.get().toInt() + vectorDrawables.useSupportLibrary = true + } + + buildTypes { + release { + isMinifyEnabled = true + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + consumerProguardFiles("proguard-rules.pro") + } + } + + buildFeatures { + viewBinding = true + compose = true + } + + composeOptions { + kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get() + } + + compileOptions { + val currentJavaVersionFromLibs = JavaVersion.valueOf(libs.versions.app.build.javaVersion.get().toString()) + sourceCompatibility = currentJavaVersionFromLibs + targetCompatibility = currentJavaVersionFromLibs + } + + tasks.withType { + kotlinOptions.jvmTarget = project.libs.versions.app.build.kotlinJVMTarget.get() + kotlinOptions.freeCompilerArgs = listOf( + "-opt-in=kotlin.RequiresOptIn", + "-Xcontext-receivers" + ) + } + + sourceSets { + getByName("main").java.srcDirs("src/main/kotlin") + } + namespace = libs.versions.app.version.groupId.get() +} + +publishing.publications { + create("release") { + groupId = libs.versions.app.version.groupId.get() + artifactId = name + version = libs.versions.app.version.versionName.get() + afterEvaluate { + from(components["release"]) + } + } +} + +dependencies { + implementation(libs.kotlinx.serialization.json) + implementation(libs.androidx.constraintlayout) + implementation(libs.androidx.documentfile) + implementation(libs.androidx.swiperefreshlayout) + implementation(libs.androidx.exifinterface) + implementation(libs.androidx.biometric.ktx) + implementation(libs.ez.vcard) + + api(libs.joda.time) + api(libs.recyclerView.fastScroller) + api(libs.reprint) + api(libs.rtl.viewpager) + api(libs.patternLockView) + api(libs.androidx.core.ktx) + api(libs.androidx.appcompat) + api(libs.material) + api(libs.gson) + + api(libs.glide) + kapt(libs.glide.compiler) + + api(libs.bundles.room) + kapt(libs.androidx.room.compiler) +} diff --git a/commons/src/main/kotlin/com/simplemobiletools/commons/activities/AboutActivity.kt b/commons/src/main/kotlin/com/simplemobiletools/commons/activities/AboutActivity.kt index 6fbebc853..fd81bc15e 100644 --- a/commons/src/main/kotlin/com/simplemobiletools/commons/activities/AboutActivity.kt +++ b/commons/src/main/kotlin/com/simplemobiletools/commons/activities/AboutActivity.kt @@ -11,13 +11,13 @@ import android.view.View import androidx.core.net.toUri import androidx.core.view.isEmpty import com.simplemobiletools.commons.R +import com.simplemobiletools.commons.databinding.ActivityAboutBinding +import com.simplemobiletools.commons.databinding.ItemAboutBinding import com.simplemobiletools.commons.dialogs.ConfirmationAdvancedDialog import com.simplemobiletools.commons.dialogs.RateStarsDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.FAQItem -import kotlinx.android.synthetic.main.activity_about.* -import kotlinx.android.synthetic.main.item_about.view.* class AboutActivity : BaseSimpleActivity() { private var appName = "" @@ -35,35 +35,36 @@ class AboutActivity : BaseSimpleActivity() { override fun getAppLauncherName() = intent.getStringExtra(APP_LAUNCHER_NAME) ?: "" + private val binding by viewBinding(ActivityAboutBinding::inflate) override fun onCreate(savedInstanceState: Bundle?) { isMaterialActivity = true super.onCreate(savedInstanceState) - setContentView(R.layout.activity_about) + setContentView(binding.root) primaryColor = getProperPrimaryColor() textColor = getProperTextColor() backgroundColor = getProperBackgroundColor() inflater = LayoutInflater.from(this) - updateMaterialActivityViews(about_coordinator, about_holder, useTransparentNavigation = true, useTopSearchMenu = false) - setupMaterialScrollListener(about_nested_scrollview, about_toolbar) + updateMaterialActivityViews(binding.aboutCoordinator, binding.aboutHolder, useTransparentNavigation = true, useTopSearchMenu = false) + setupMaterialScrollListener(binding.aboutNestedScrollview, binding.aboutToolbar) appName = intent.getStringExtra(APP_NAME) ?: "" - arrayOf(about_support, about_help_us, about_social, about_other).forEach { + arrayOf(binding.aboutSupport, binding.aboutHelpUs, binding.aboutSocial, binding.aboutOther).forEach { it.setTextColor(primaryColor) } } override fun onResume() { super.onResume() - updateTextColors(about_nested_scrollview) - setupToolbar(about_toolbar, NavigationIcon.Arrow) + updateTextColors(binding.aboutNestedScrollview) + setupToolbar(binding.aboutToolbar, NavigationIcon.Arrow) - about_support_layout.removeAllViews() - about_help_us_layout.removeAllViews() - about_social_layout.removeAllViews() - about_other_layout.removeAllViews() + binding.aboutSupportLayout.removeAllViews() + binding.aboutHelpUsLayout.removeAllViews() + binding.aboutSocialLayout.removeAllViews() + binding.aboutOtherLayout.removeAllViews() setupFAQ() setupEmail() @@ -85,12 +86,14 @@ class AboutActivity : BaseSimpleActivity() { private fun setupFAQ() { val faqItems = intent.getSerializableExtra(APP_FAQ) as ArrayList if (faqItems.isNotEmpty()) { - inflater?.inflate(R.layout.item_about, null)?.apply { - setupAboutItem(this, R.drawable.ic_question_mark_vector, R.string.frequently_asked_questions) - about_support_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + setupAboutItem(this, R.drawable.ic_question_mark_vector, R.string.frequently_asked_questions) + binding.aboutSupportLayout.addView(root) - setOnClickListener { - launchFAQActivity() + root.setOnClickListener { + launchFAQActivity() + } } } } @@ -108,31 +111,33 @@ class AboutActivity : BaseSimpleActivity() { private fun setupEmail() { if (resources.getBoolean(R.bool.hide_all_external_links)) { - if (about_support_layout.isEmpty()) { - about_support.beGone() - about_support_divider.beGone() + if (binding.aboutSupportLayout.isEmpty()) { + binding.aboutSupport.beGone() + binding.aboutSupportDivider.beGone() } return } - inflater?.inflate(R.layout.item_about, null)?.apply { - setupAboutItem(this, R.drawable.ic_mail_vector, R.string.my_email) - about_support_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + setupAboutItem(this, R.drawable.ic_mail_vector, R.string.my_email) + binding.aboutSupportLayout.addView(root) - setOnClickListener { - val msg = "${getString(R.string.before_asking_question_read_faq)}\n\n${getString(R.string.make_sure_latest)}" - if (intent.getBooleanExtra(SHOW_FAQ_BEFORE_MAIL, false) && !baseConfig.wasBeforeAskingShown) { - baseConfig.wasBeforeAskingShown = true - ConfirmationAdvancedDialog(this@AboutActivity, msg, 0, R.string.read_faq, R.string.skip) { success -> - if (success) { - launchFAQActivity() - } else { - launchEmailIntent() + root.setOnClickListener { + val msg = "${getString(R.string.before_asking_question_read_faq)}\n\n${getString(R.string.make_sure_latest)}" + if (intent.getBooleanExtra(SHOW_FAQ_BEFORE_MAIL, false) && !baseConfig.wasBeforeAskingShown) { + baseConfig.wasBeforeAskingShown = true + ConfirmationAdvancedDialog(this@AboutActivity, msg, 0, R.string.read_faq, R.string.skip) { success -> + if (success) { + launchFAQActivity() + } else { + launchEmailIntent() + } } + } else { + launchEmailIntent() } - } else { - launchEmailIntent() } } } @@ -179,21 +184,23 @@ class AboutActivity : BaseSimpleActivity() { return } - inflater?.inflate(R.layout.item_about, null)?.apply { - setupAboutItem(this, R.drawable.ic_star_vector, R.string.rate_us) - about_help_us_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + setupAboutItem(this, R.drawable.ic_star_vector, R.string.rate_us) + binding.aboutHelpUsLayout.addView(root) - setOnClickListener { - if (baseConfig.wasBeforeRateShown) { - launchRateUsPrompt() - } else { - baseConfig.wasBeforeRateShown = true - val msg = "${getString(R.string.before_rate_read_faq)}\n\n${getString(R.string.make_sure_latest)}" - ConfirmationAdvancedDialog(this@AboutActivity, msg, 0, R.string.read_faq, R.string.skip) { success -> - if (success) { - launchFAQActivity() - } else { - launchRateUsPrompt() + root.setOnClickListener { + if (baseConfig.wasBeforeRateShown) { + launchRateUsPrompt() + } else { + baseConfig.wasBeforeRateShown = true + val msg = "${getString(R.string.before_rate_read_faq)}\n\n${getString(R.string.make_sure_latest)}" + ConfirmationAdvancedDialog(this@AboutActivity, msg, 0, R.string.read_faq, R.string.skip) { success -> + if (success) { + launchFAQActivity() + } else { + launchRateUsPrompt() + } } } } @@ -214,43 +221,49 @@ class AboutActivity : BaseSimpleActivity() { return } - inflater?.inflate(R.layout.item_about, null)?.apply { - setupAboutItem(this, R.drawable.ic_add_person_vector, R.string.invite_friends) - about_help_us_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + setupAboutItem(this, R.drawable.ic_add_person_vector, R.string.invite_friends) + binding.aboutHelpUsLayout.addView(root) - setOnClickListener { - val text = String.format(getString(R.string.share_text), appName, getStoreUrl()) - Intent().apply { - action = ACTION_SEND - putExtra(EXTRA_SUBJECT, appName) - putExtra(EXTRA_TEXT, text) - type = "text/plain" - startActivity(createChooser(this, getString(R.string.invite_via))) + root.setOnClickListener { + val text = String.format(getString(R.string.share_text), appName, getStoreUrl()) + Intent().apply { + action = ACTION_SEND + putExtra(EXTRA_SUBJECT, appName) + putExtra(EXTRA_TEXT, text) + type = "text/plain" + startActivity(createChooser(this, getString(R.string.invite_via))) + } } } } } private fun setupContributors() { - inflater?.inflate(R.layout.item_about, null)?.apply { - setupAboutItem(this, R.drawable.ic_face_vector, R.string.contributors) - about_help_us_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + setupAboutItem(this, R.drawable.ic_face_vector, R.string.contributors) + binding.aboutHelpUsLayout.addView(root) - setOnClickListener { - val intent = Intent(applicationContext, ContributorsActivity::class.java) - startActivity(intent) + root.setOnClickListener { + val intent = Intent(applicationContext, ContributorsActivity::class.java) + startActivity(intent) + } } } } private fun setupDonate() { if (resources.getBoolean(R.bool.show_donate_in_about) && !resources.getBoolean(R.bool.hide_all_external_links)) { - inflater?.inflate(R.layout.item_about, null)?.apply { - setupAboutItem(this, R.drawable.ic_dollar_vector, R.string.donate) - about_help_us_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + setupAboutItem(this, R.drawable.ic_dollar_vector, R.string.donate) + binding.aboutHelpUsLayout.addView(root) - setOnClickListener { - launchViewIntent(getString(R.string.donate_url)) + root.setOnClickListener { + launchViewIntent(getString(R.string.donate_url)) + } } } } @@ -261,21 +274,23 @@ class AboutActivity : BaseSimpleActivity() { return } - inflater?.inflate(R.layout.item_about, null)?.apply { - about_item_icon.setImageResource(R.drawable.ic_facebook_vector) - about_item_label.setText(R.string.facebook) - about_item_label.setTextColor(textColor) - about_social_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + aboutItemIcon.setImageResource(R.drawable.ic_facebook_vector) + aboutItemLabel.setText(R.string.facebook) + aboutItemLabel.setTextColor(textColor) + binding.aboutSocialLayout.addView(root) - setOnClickListener { - var link = "https://www.facebook.com/simplemobiletools" - try { - packageManager.getPackageInfo("com.facebook.katana", 0) - link = "fb://page/150270895341774" - } catch (ignored: Exception) { + root.setOnClickListener { + var link = "https://www.facebook.com/simplemobiletools" + try { + packageManager.getPackageInfo("com.facebook.katana", 0) + link = "fb://page/150270895341774" + } catch (ignored: Exception) { + } + + launchViewIntent(link) } - - launchViewIntent(link) } } } @@ -285,14 +300,16 @@ class AboutActivity : BaseSimpleActivity() { return } - inflater?.inflate(R.layout.item_about, null)?.apply { - about_item_icon.setImageDrawable(resources.getColoredDrawableWithColor(R.drawable.ic_github_vector, backgroundColor.getContrastColor())) - about_item_label.setText(R.string.github) - about_item_label.setTextColor(textColor) - about_social_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + aboutItemIcon.setImageDrawable(resources.getColoredDrawableWithColor(R.drawable.ic_github_vector, backgroundColor.getContrastColor())) + aboutItemLabel.setText(R.string.github) + aboutItemLabel.setTextColor(textColor) + binding.aboutSocialLayout.addView(root) - setOnClickListener { - launchViewIntent("https://github.com/SimpleMobileTools") + root.setOnClickListener { + launchViewIntent("https://github.com/SimpleMobileTools") + } } } } @@ -302,36 +319,40 @@ class AboutActivity : BaseSimpleActivity() { return } - inflater?.inflate(R.layout.item_about, null)?.apply { - about_item_icon.setImageResource(R.drawable.ic_reddit_vector) - about_item_label.setText(R.string.reddit) - about_item_label.setTextColor(textColor) - about_social_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + aboutItemIcon.setImageResource(R.drawable.ic_reddit_vector) + aboutItemLabel.setText(R.string.reddit) + aboutItemLabel.setTextColor(textColor) + binding.aboutSocialLayout.addView(root) - setOnClickListener { - launchViewIntent("https://www.reddit.com/r/SimpleMobileTools") + root.setOnClickListener { + launchViewIntent("https://www.reddit.com/r/SimpleMobileTools") + } } } } private fun setupTelegram() { if (resources.getBoolean(R.bool.hide_all_external_links)) { - if (about_social_layout.isEmpty()) { - about_social.beGone() - about_social_divider.beGone() + if (binding.aboutSocialLayout.isEmpty()) { + binding.aboutSocial.beGone() + binding.aboutSocialDivider.beGone() } return } - inflater?.inflate(R.layout.item_about, null)?.apply { - about_item_icon.setImageResource(R.drawable.ic_telegram_vector) - about_item_label.setText(R.string.telegram) - about_item_label.setTextColor(textColor) - about_social_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + aboutItemIcon.setImageResource(R.drawable.ic_telegram_vector) + aboutItemLabel.setText(R.string.telegram) + aboutItemLabel.setTextColor(textColor) + binding.aboutSocialLayout.addView(root) - setOnClickListener { - launchViewIntent("https://t.me/SimpleMobileTools") + root.setOnClickListener { + launchViewIntent("https://t.me/SimpleMobileTools") + } } } } @@ -341,12 +362,14 @@ class AboutActivity : BaseSimpleActivity() { return } - inflater?.inflate(R.layout.item_about, null)?.apply { - setupAboutItem(this, R.drawable.ic_heart_vector, R.string.more_apps_from_us) - about_other_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + setupAboutItem(this, R.drawable.ic_heart_vector, R.string.more_apps_from_us) + binding.aboutOtherLayout.addView(root) - setOnClickListener { - launchMoreAppsFromUsIntent() + root.setOnClickListener { + launchMoreAppsFromUsIntent() + } } } } @@ -356,12 +379,14 @@ class AboutActivity : BaseSimpleActivity() { return } - inflater?.inflate(R.layout.item_about, null)?.apply { - setupAboutItem(this, R.drawable.ic_link_vector, R.string.website) - about_other_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + setupAboutItem(this, R.drawable.ic_link_vector, R.string.website) + binding.aboutOtherLayout.addView(root) - setOnClickListener { - launchViewIntent("https://simplemobiletools.com/") + root.setOnClickListener { + launchViewIntent("https://simplemobiletools.com/") + } } } } @@ -371,29 +396,33 @@ class AboutActivity : BaseSimpleActivity() { return } - inflater?.inflate(R.layout.item_about, null)?.apply { - setupAboutItem(this, R.drawable.ic_unhide_vector, R.string.privacy_policy) - about_other_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + setupAboutItem(this, R.drawable.ic_unhide_vector, R.string.privacy_policy) + binding.aboutOtherLayout.addView(root) - setOnClickListener { - val appId = baseConfig.appId.removeSuffix(".debug").removeSuffix(".pro").removePrefix("com.simplemobiletools.") - val url = "https://simplemobiletools.com/privacy/$appId.txt" - launchViewIntent(url) + root.setOnClickListener { + val appId = baseConfig.appId.removeSuffix(".debug").removeSuffix(".pro").removePrefix("com.simplemobiletools.") + val url = "https://simplemobiletools.com/privacy/$appId.txt" + launchViewIntent(url) + } } } } private fun setupLicense() { - inflater?.inflate(R.layout.item_about, null)?.apply { - setupAboutItem(this, R.drawable.ic_article_vector, R.string.third_party_licences) - about_other_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + setupAboutItem(this, R.drawable.ic_article_vector, R.string.third_party_licences) + binding.aboutOtherLayout.addView(root) - setOnClickListener { - Intent(applicationContext, LicenseActivity::class.java).apply { - putExtra(APP_ICON_IDS, getAppIconIDs()) - putExtra(APP_LAUNCHER_NAME, getAppLauncherName()) - putExtra(APP_LICENSES, intent.getLongExtra(APP_LICENSES, 0)) - startActivity(this) + root.setOnClickListener { + Intent(applicationContext, LicenseActivity::class.java).apply { + putExtra(APP_ICON_IDS, getAppIconIDs()) + putExtra(APP_LAUNCHER_NAME, getAppLauncherName()) + putExtra(APP_LICENSES, intent.getLongExtra(APP_LICENSES, 0)) + startActivity(this) + } } } } @@ -405,37 +434,39 @@ class AboutActivity : BaseSimpleActivity() { version += " ${getString(R.string.pro)}" } - inflater?.inflate(R.layout.item_about, null)?.apply { - about_item_icon.setImageDrawable(resources.getColoredDrawableWithColor(R.drawable.ic_info_vector, textColor)) - val fullVersion = String.format(getString(R.string.version_placeholder, version)) - about_item_label.text = fullVersion - about_item_label.setTextColor(textColor) - about_other_layout.addView(this) + inflater?.let { + ItemAboutBinding.inflate(it, null, false).apply { + aboutItemIcon.setImageDrawable(resources.getColoredDrawableWithColor(R.drawable.ic_info_vector, textColor)) + val fullVersion = String.format(getString(R.string.version_placeholder, version)) + aboutItemLabel.text = fullVersion + aboutItemLabel.setTextColor(textColor) + binding.aboutOtherLayout.addView(root) - setOnClickListener { - if (firstVersionClickTS == 0L) { - firstVersionClickTS = System.currentTimeMillis() - Handler().postDelayed({ + root.setOnClickListener { + if (firstVersionClickTS == 0L) { + firstVersionClickTS = System.currentTimeMillis() + Handler().postDelayed({ + firstVersionClickTS = 0L + clicksSinceFirstClick = 0 + }, EASTER_EGG_TIME_LIMIT) + } + + clicksSinceFirstClick++ + if (clicksSinceFirstClick >= EASTER_EGG_REQUIRED_CLICKS) { + toast(R.string.hello) firstVersionClickTS = 0L clicksSinceFirstClick = 0 - }, EASTER_EGG_TIME_LIMIT) - } - - clicksSinceFirstClick++ - if (clicksSinceFirstClick >= EASTER_EGG_REQUIRED_CLICKS) { - toast(R.string.hello) - firstVersionClickTS = 0L - clicksSinceFirstClick = 0 + } } } } } - private fun setupAboutItem(view: View, drawableId: Int, textId: Int) { + private fun setupAboutItem(view: ItemAboutBinding, drawableId: Int, textId: Int) { view.apply { - about_item_icon.setImageDrawable(resources.getColoredDrawableWithColor(drawableId, textColor)) - about_item_label.setText(textId) - about_item_label.setTextColor(textColor) + aboutItemIcon.setImageDrawable(resources.getColoredDrawableWithColor(drawableId, textColor)) + aboutItemLabel.setText(textId) + aboutItemLabel.setTextColor(textColor) } } } diff --git a/commons/src/main/kotlin/com/simplemobiletools/commons/activities/ContributorsActivity.kt b/commons/src/main/kotlin/com/simplemobiletools/commons/activities/ContributorsActivity.kt index 4b3df1952..884bd0625 100644 --- a/commons/src/main/kotlin/com/simplemobiletools/commons/activities/ContributorsActivity.kt +++ b/commons/src/main/kotlin/com/simplemobiletools/commons/activities/ContributorsActivity.kt @@ -5,31 +5,33 @@ import android.text.Html import android.text.method.LinkMovementMethod import android.view.LayoutInflater import com.simplemobiletools.commons.R +import com.simplemobiletools.commons.databinding.ActivityContributorsBinding +import com.simplemobiletools.commons.databinding.ItemLanguageContributorBinding import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.APP_ICON_IDS import com.simplemobiletools.commons.helpers.APP_LAUNCHER_NAME import com.simplemobiletools.commons.helpers.NavigationIcon import com.simplemobiletools.commons.models.LanguageContributor -import kotlinx.android.synthetic.main.activity_contributors.* -import kotlinx.android.synthetic.main.item_language_contributor.view.* class ContributorsActivity : BaseSimpleActivity() { override fun getAppIconIDs() = intent.getIntegerArrayListExtra(APP_ICON_IDS) ?: ArrayList() override fun getAppLauncherName() = intent.getStringExtra(APP_LAUNCHER_NAME) ?: "" + private val binding by viewBinding(ActivityContributorsBinding::inflate) + override fun onCreate(savedInstanceState: Bundle?) { isMaterialActivity = true super.onCreate(savedInstanceState) - setContentView(R.layout.activity_contributors) - updateTextColors(contributors_holder) + setContentView(binding.root) + updateTextColors(binding.contributorsHolder) - updateMaterialActivityViews(contributors_coordinator, contributors_holder, useTransparentNavigation = true, useTopSearchMenu = false) - setupMaterialScrollListener(contributors_nested_scrollview, contributors_toolbar) + updateMaterialActivityViews(binding.contributorsCoordinator, binding.contributorsHolder, useTransparentNavigation = true, useTopSearchMenu = false) + setupMaterialScrollListener(binding.contributorsNestedScrollview, binding.contributorsToolbar) val primaryColor = getProperPrimaryColor() - contributors_development_label.setTextColor(primaryColor) - contributors_translation_label.setTextColor(primaryColor) + binding.contributorsDevelopmentLabel.setTextColor(primaryColor) + binding.contributorsTranslationLabel.setTextColor(primaryColor) val inflater = LayoutInflater.from(this) val languages = arrayListOf() @@ -80,23 +82,23 @@ class ContributorsActivity : BaseSimpleActivity() { val textColor = getProperTextColor() languages.forEach { language -> - inflater.inflate(R.layout.item_language_contributor, null).apply { - language_icon.setImageDrawable(getDrawable(language.iconId)) - language_label.apply { + ItemLanguageContributorBinding.inflate(inflater).apply { + languageIcon.setImageDrawable(getDrawable(language.iconId)) + languageLabel.apply { text = getString(language.labelId) setTextColor(textColor) } - language_contributors.apply { + languageContributors.apply { text = getString(language.contributorsId) setTextColor(textColor) } - contributors_languages_holder.addView(this) + binding.contributorsLanguagesHolder.addView(root) } } - contributors_label.apply { + binding.contributorsLabel.apply { setTextColor(textColor) text = Html.fromHtml(getString(R.string.contributors_label)) setLinkTextColor(primaryColor) @@ -104,16 +106,16 @@ class ContributorsActivity : BaseSimpleActivity() { removeUnderlines() } - contributors_development_icon.applyColorFilter(textColor) - contributors_footer_icon.applyColorFilter(textColor) + binding.contributorsDevelopmentIcon.applyColorFilter(textColor) + binding.contributorsFooterIcon.applyColorFilter(textColor) if (resources.getBoolean(R.bool.hide_all_external_links)) { - contributors_footer_layout.beGone() + binding.contributorsFooterLayout.beGone() } } override fun onResume() { super.onResume() - setupToolbar(contributors_toolbar, NavigationIcon.Arrow) + setupToolbar(binding.contributorsToolbar, NavigationIcon.Arrow) } } diff --git a/commons/src/main/kotlin/com/simplemobiletools/commons/activities/CustomizationActivity.kt b/commons/src/main/kotlin/com/simplemobiletools/commons/activities/CustomizationActivity.kt index 9f9e1699c..9106792ad 100644 --- a/commons/src/main/kotlin/com/simplemobiletools/commons/activities/CustomizationActivity.kt +++ b/commons/src/main/kotlin/com/simplemobiletools/commons/activities/CustomizationActivity.kt @@ -6,6 +6,7 @@ import android.graphics.drawable.LayerDrawable import android.graphics.drawable.RippleDrawable import android.os.Bundle import com.simplemobiletools.commons.R +import com.simplemobiletools.commons.databinding.ActivityCustomizationBinding import com.simplemobiletools.commons.dialogs.* import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* @@ -45,6 +46,8 @@ class CustomizationActivity : BaseSimpleActivity() { override fun getAppLauncherName() = intent.getStringExtra(APP_LAUNCHER_NAME) ?: "" + private val binding by viewBinding(ActivityCustomizationBinding::inflate) + override fun onCreate(savedInstanceState: Bundle?) { isMaterialActivity = true super.onCreate(savedInstanceState) diff --git a/commons/src/main/kotlin/com/simplemobiletools/commons/extensions/Binding.kt b/commons/src/main/kotlin/com/simplemobiletools/commons/extensions/Binding.kt new file mode 100644 index 000000000..23fe85ee5 --- /dev/null +++ b/commons/src/main/kotlin/com/simplemobiletools/commons/extensions/Binding.kt @@ -0,0 +1,11 @@ +package com.simplemobiletools.commons.extensions + +import android.app.Activity +import android.view.LayoutInflater +import androidx.viewbinding.ViewBinding + +inline fun Activity.viewBinding(crossinline bindingInflater: (LayoutInflater) -> T) = + lazy(LazyThreadSafetyMode.NONE) { + bindingInflater.invoke(layoutInflater) + } + diff --git a/commons/src/main/kotlin/com/simplemobiletools/commons/views/bottomactionmenu/BottomActionMenuItemPopup.kt b/commons/src/main/kotlin/com/simplemobiletools/commons/views/bottomactionmenu/BottomActionMenuItemPopup.kt index b0dc9c224..07dc01a75 100644 --- a/commons/src/main/kotlin/com/simplemobiletools/commons/views/bottomactionmenu/BottomActionMenuItemPopup.kt +++ b/commons/src/main/kotlin/com/simplemobiletools/commons/views/bottomactionmenu/BottomActionMenuItemPopup.kt @@ -12,10 +12,10 @@ import android.widget.PopupWindow import androidx.core.content.ContextCompat import androidx.core.widget.PopupWindowCompat import com.simplemobiletools.commons.R +import com.simplemobiletools.commons.databinding.ItemActionModePopupBinding import com.simplemobiletools.commons.extensions.applyColorFilter import com.simplemobiletools.commons.extensions.windowManager import com.simplemobiletools.commons.helpers.isRPlus -import kotlinx.android.synthetic.main.item_action_mode_popup.view.cab_item class BottomActionMenuItemPopup( private val context: Context, @@ -38,25 +38,25 @@ class BottomActionMenuItemPopup( private val popupListAdapter = object : ArrayAdapter(context, R.layout.item_action_mode_popup, items) { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { - var view = convertView + var view: ItemActionModePopupBinding? = null if (view == null) { - view = LayoutInflater.from(context).inflate(R.layout.item_action_mode_popup, parent, false) + view = ItemActionModePopupBinding.inflate(LayoutInflater.from(context), parent, false) } val item = items[position] - view!!.cab_item.text = item.title + view.cabItem.text = item.title if (item.icon != View.NO_ID) { val icon = ContextCompat.getDrawable(context, item.icon) icon?.applyColorFilter(Color.WHITE) - view.cab_item.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null) + view.cabItem.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null) } - view.setOnClickListener { + view.root.setOnClickListener { onSelect.invoke(item) popup.dismiss() } - return view + return view.root } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 000000000..2f45edf4e --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,143 @@ +[versions] +#jetbrains +ezVcard = "0.11.3" +gson = "2.10.1" +jodaTime = "2.12.4" +kotlin = "1.9.0" +#KSP +kotlinxSerializationJson = "1.5.1" +ksp = "1.9.0-1.0.12" +#Androidx +androidx-customView = "1.2.0-alpha02" +androidx-customViewPooling = "1.0.0" +androidx-lifecycle = "2.6.1" +androidx-constraintlayout = "2.1.4" +androidx-documentfile = "1.0.1" +androidx-biometricKtx = "1.2.0-alpha05" +androidx-exifinterface = "1.3.6" +androidx-coreKtx = "1.10.1" +androidx-appcompat = "1.6.1" +androidx-swiperefreshlayout = "1.1.0" +#Material +material = "1.9.0" +#patternLockView +patternLockView = "a90b0d4bf0" +#reprint +reprint = "2cb206415d" +#recyclerviewFastscroller +recyclerviewFastscroller = "5a95285b1f" +#rtlViewpager +rtlViewpager = "940f12724f" +#Compose +composeActivity = "1.8.0-alpha06" +compose = "1.6.0-alpha01" +composeCompiler = "1.5.0" +composeMaterial3 = "1.2.0-alpha03" +accompanist = "0.31.5-beta" +#Glide +glide = "4.15.1" +#Room +room = "2.5.2" +#Publish +androidMavenGradlePlugin = "2.1" +#Gradle +gradlePlugins-agp = "8.0.1" +#build +app-build-compileSDKVersion = "34" +app-build-targetSDK = "34" +app-build-minimumSDK = "23" +app-build-javaVersion = "VERSION_17" +app-build-kotlinJVMTarget = "17" +#versioning +app-version-appId = "com.simplemobiletools.commons" +app-version-groupId = "com.simplemobiletools.commons" +app-version-versionCode = "1" +app-version-versionName = "5.34.26" +[libraries] +#Android X +androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" } +androidx-biometric-ktx = { module = "androidx.biometric:biometric-ktx", version.ref = "androidx-biometricKtx" } +androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "androidx-constraintlayout" } +androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-coreKtx" } +androidx-customView = { module = "androidx.customview:customview", version.ref = "androidx-customView" } +androidx-customViewPooling = { module = "androidx.customview:customview-poolingcontainer", version.ref = "androidx-customViewPooling" } +androidx-documentfile = { module = "androidx.documentfile:documentfile", version.ref = "androidx-documentfile" } +androidx-exifinterface = { module = "androidx.exifinterface:exifinterface", version.ref = "androidx-exifinterface" } +androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version.ref = "androidx-swiperefreshlayout" } +#Android X lifecycle +androidx-lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidx-lifecycle" } +androidx-lifecycle-viewModel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" } +androidx-lifecycle-viewModel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" } +androidx-lifecycle-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" } +#Room +androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } +androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" } +androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } +#Compose +compose-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "composeCompiler" } +compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" } +compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "composeMaterial3" } +compose-material2 = { module = "androidx.compose.material:material", version.ref = "compose" } +compose-material-icons = { module = "androidx.compose.material:material-icons-extended", version.ref = "compose" } +compose-animation = { module = "androidx.compose.animation:animation", version.ref = "compose" } +compose-activity = { module = "androidx.activity:activity-compose", version.ref = "composeActivity" } +compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" } +compose-runtime = { module = "androidx.compose.runtime:runtime", version.ref = "compose" } +compose-uiTooling-debug = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" } +compose-uiTooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" } +#Accompanist +accompanist-systemuicontroller = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanist" } +#Glide +glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" } +glide-compiler = { module = "com.github.bumptech.glide:compiler", version.ref = "glide" } +#Material +material = { module = "com.google.android.material:material", version.ref = "material" } +#Helpers +patternLockView = { module = "com.github.aritraroy:patternLockView", version.ref = "patternLockView" } +reprint = { module = "com.github.tibbi:reprint", version.ref = "reprint" } +recyclerView-FastScroller = { module = "com.github.tibbi:RecyclerView-FastScroller", version.ref = "recyclerviewFastscroller" } +rtl-viewpager = { module = "com.github.duolingo:rtl-viewpager", version.ref = "rtlViewpager" } +ez-vcard = { module = "com.googlecode.ez-vcard:ez-vcard", version.ref = "ezVcard" } +gson = { module = "com.google.code.gson:gson", version.ref = "gson" } +joda-time = { module = "joda-time:joda-time", version.ref = "jodaTime" } +#Kotlin +kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } +[bundles] +compose = [ + "compose-activity", + "compose-animation", + "compose-compiler", + "compose-foundation", + "compose-material-icons", + "compose-material3", + "compose-runtime", + "compose-ui", + "compose-uiTooling-preview", +] +compose-preview = [ + "androidx-customView", + "androidx-customViewPooling", + "compose-uiTooling-debug", +] +room = [ + "androidx-room-ktx", + "androidx-room-runtime", +] +accompanist = [ + "accompanist-systemuicontroller", +] +lifecycle = [ + "androidx-lifecycle-compose", + "androidx-lifecycle-runtime", + "androidx-lifecycle-viewModel", + "androidx-lifecycle-viewModel-compose", +] +[plugins] +android = { id = "com.android.application", version.ref = "gradlePlugins-agp" } +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } +library = { id = "com.android.library", version.ref = "gradlePlugins-agp" } +kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlinAndroidExtensions = { id = "org.jetbrains.kotlin.android.extensions", version.ref = "kotlin" } +kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" } +parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4bf251d66..34a2d71ad 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip diff --git a/jitpack.yml b/jitpack.yml index adb3fe10c..bb8a4f69e 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,2 +1 @@ -jdk: - - openjdk11 +jdk: openjdk17 diff --git a/samples/build.gradle b/samples/build.gradle deleted file mode 100644 index 0d40c250d..000000000 --- a/samples/build.gradle +++ /dev/null @@ -1,34 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' - -android { - compileSdkVersion propCompileSdkVersion - - defaultConfig { - applicationId "com.simplemobiletools.commons" - minSdkVersion propMinSdkVersion - targetSdkVersion propTargetSdkVersion - versionCode propVersionCode - versionName propVersionName - vectorDrawables.useSupportLibrary = true - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } -} - -dependencies { - implementation project(':commons') - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'com.google.android.material:material:1.6.1' - implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' -} diff --git a/samples/build.gradle.kts b/samples/build.gradle.kts new file mode 100644 index 000000000..1ade1cbb7 --- /dev/null +++ b/samples/build.gradle.kts @@ -0,0 +1,39 @@ +plugins { + alias(libs.plugins.android) + alias(libs.plugins.kotlinAndroid) + alias(libs.plugins.kotlinAndroidExtensions) +} +android { + compileSdk = libs.versions.app.build.compileSDKVersion.get().toInt() + + defaultConfig { + applicationId = libs.versions.app.version.appId.get() + minSdk = libs.versions.app.build.minimumSDK.get().toInt() + targetSdk = libs.versions.app.build.targetSDK.get().toInt() + versionName = libs.versions.app.version.versionName.get() + versionCode = libs.versions.app.version.versionCode.get().toInt() + vectorDrawables.useSupportLibrary = true + } + + + buildTypes { + release { + isMinifyEnabled = true + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + + sourceSets { + getByName("main").java.srcDirs("src/main/kotlin") + } + namespace = "com.simplemobiletools.commons.samples" +} + +dependencies { + implementation(projects.commons) + implementation(libs.material) + implementation(libs.androidx.swiperefreshlayout) +} diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index da47d9919..000000000 --- a/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include ':samples', ':commons' diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 000000000..7669f3152 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,17 @@ +pluginManagement { + repositories { + gradlePluginPortal() + google() + mavenCentral() + } +} +dependencyResolutionManagement { + //repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + maven { setUrl("https://jitpack.io") } + } +} +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") +include(":samples", "commons")