diff --git a/actionChooser/build.gradle b/actionChooser/build.gradle
deleted file mode 100644
index dc23dbf..0000000
--- a/actionChooser/build.gradle
+++ /dev/null
@@ -1,29 +0,0 @@
-plugins {
- id 'com.android.library'
- id 'kotlin-android'
- id 'kotlin-kapt'
-}
-
-android {
- compileSdk 30
-
- defaultConfig {
- minSdk 21
- }
-
- buildTypes {
- release {
- minifyEnabled true
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-
- viewBinding {
- enabled true
- }
-}
-
-dependencies {
- implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0-alpha03"
- implementation "com.google.android.material:material:1.4.0"
-}
\ No newline at end of file
diff --git a/actionChooser/build.gradle.kts b/actionChooser/build.gradle.kts
new file mode 100644
index 0000000..f0ff11f
--- /dev/null
+++ b/actionChooser/build.gradle.kts
@@ -0,0 +1,39 @@
+plugins {
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.android.kotlin)
+}
+
+android {
+ namespace = "codes.mina_mikhail.action_chooser"
+ compileSdk = 34
+
+ defaultConfig {
+ minSdk = 21
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = true
+ proguardFiles (getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+
+ kotlinOptions {
+ jvmTarget = JavaVersion.VERSION_17.toString()
+ }
+
+ buildFeatures {
+ viewBinding = true
+ }
+
+}
+
+dependencies {
+ implementation(libs.lifecycle)
+ implementation(libs.materialDesign)
+}
\ No newline at end of file
diff --git a/actionChooser/proguard-rules.pro b/actionChooser/proguard-rules.pro
index 481bb43..ff59496 100644
--- a/actionChooser/proguard-rules.pro
+++ b/actionChooser/proguard-rules.pro
@@ -1,6 +1,6 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
+# proguardFiles setting in build.gradle.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
diff --git a/actionChooser/src/main/AndroidManifest.xml b/actionChooser/src/main/AndroidManifest.xml
index 596b932..1d26c87 100644
--- a/actionChooser/src/main/AndroidManifest.xml
+++ b/actionChooser/src/main/AndroidManifest.xml
@@ -1,6 +1,2 @@
-
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index b17635c..65e7195 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,36 +1,38 @@
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
plugins {
- id(Config.Plugins.androidApplication)
- id(Config.Plugins.kotlinAndroid)
- id(Config.Plugins.kotlinKapt)
- id(Config.Plugins.navigationSafeArgs)
- id(Config.Plugins.hilt)
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.android.kotlin)
+ alias(libs.plugins.kotlin.ksp)
+ alias(libs.plugins.navigation.safeargs)
+ alias(libs.plugins.dagger.hilt.android)
+ alias(libs.plugins.googleServices)
}
android {
- compileSdk = Config.AppConfig.compileSdkVersion
+ namespace = "com.mina_mikhail.base_mvvm"
+ compileSdk = 34
defaultConfig {
- applicationId = Config.AppConfig.appId
- minSdk = Config.AppConfig.minSdkVersion
- targetSdk = Config.AppConfig.compileSdkVersion
- versionCode = Config.AppConfig.versionCode
- versionName = Config.AppConfig.versionName
+ applicationId = "com.mina_mikhail.base_mvvm"
+ minSdk = 21
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0"
vectorDrawables.useSupportLibrary = true
multiDexEnabled = true
- testInstrumentationRunner = Config.AppConfig.testRunner
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
- getByName("debug") {
- resValue("string", "google_api_key", gradleLocalProperties(rootDir).getProperty("GOOGLE_API_KEY"))
+ debug{
+// resValue("string", "google_api_key", gradleLocalProperties(rootDir).getProperty("GOOGLE_API_KEY"))
manifestPlaceholders["appName"] = "@string/app_name_debug"
manifestPlaceholders["appIcon"] = "@mipmap/ic_launcher_debug"
manifestPlaceholders["appRoundIcon"] = "@mipmap/ic_launcher_debug_round"
- buildConfigField("String", "API_BASE_URL", Config.Environments.debugBaseUrl)
+ buildConfigField("String", "API_BASE_URL", "http://url.to.server/api/")
}
signingConfigs {
@@ -42,32 +44,33 @@ android {
}
}
- getByName("release") {
+ release{
signingConfig = signingConfigs.getByName("releaseConfig")
isMinifyEnabled = true
isShrinkResources = true
- resValue("string", "google_api_key", gradleLocalProperties(rootDir).getProperty("GOOGLE_API_KEY"))
+// resValue("string", "google_api_key", gradleLocalProperties(rootDir).getProperty("GOOGLE_API_KEY"))
manifestPlaceholders["appName"] = "@string/app_name"
manifestPlaceholders["appIcon"] = "@mipmap/ic_launcher"
manifestPlaceholders["appRoundIcon"] = "@mipmap/ic_launcher_round"
- buildConfigField("String", "API_BASE_URL", Config.Environments.releaseBaseUrl)
+ buildConfigField("String", "API_BASE_URL", "http://url.to.server/api/")
}
}
compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
- jvmTarget = "11"
+ jvmTarget = JavaVersion.VERSION_17.toString()
}
- dataBinding {
- isEnabled = true
+ buildFeatures {
+ buildConfig = true
+ dataBinding = true
}
}
@@ -75,23 +78,20 @@ dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
// Networking
- implementation(Libraries.retrofit)
- implementation(Libraries.retrofitConverter)
- implementation(Libraries.gson)
- implementation(Libraries.interceptor)
- implementation(Libraries.chuckLogging)
+ implementation(libs.bundles.networking)
// Utils
- implementation(Libraries.playServices)
- implementation(Libraries.localization)
- implementation(Libraries.multidex)
+
+ implementation(libs.playServices)
+ implementation(libs.localization)
+ implementation(libs.multidex)
// Hilt
- implementation(Libraries.hilt)
- kapt(Libraries.hiltDaggerCompiler)
+ implementation(libs.hilt)
+ ksp(libs.hiltDaggerCompiler)
// Project Modules
- implementation(project(Config.Modules.domain))
- implementation(project(Config.Modules.data))
- implementation(project(Config.Modules.presentation))
+ implementation(projects.domain)
+ implementation(projects.data)
+ implementation(projects.presentation)
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index dbf5aa3..e5a1de2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,7 +1,6 @@
+ xmlns:tools="http://schemas.android.com/tools">
diff --git a/app/src/main/java/com/mina_mikhail/base_mvvm/core/MyApplication.kt b/app/src/main/java/com/mina_mikhail/base_mvvm/core/MyApplication.kt
index e570c84..d73f34c 100644
--- a/app/src/main/java/com/mina_mikhail/base_mvvm/core/MyApplication.kt
+++ b/app/src/main/java/com/mina_mikhail/base_mvvm/core/MyApplication.kt
@@ -2,14 +2,8 @@ package com.mina_mikhail.base_mvvm.core
import android.content.Context
import androidx.multidex.MultiDex
-import com.google.android.gms.common.GooglePlayServicesNotAvailableException
-import com.google.android.gms.common.GooglePlayServicesRepairableException
-import com.google.android.gms.security.ProviderInstaller
import com.zeugmasolutions.localehelper.LocaleAwareApplication
import dagger.hilt.android.HiltAndroidApp
-import java.security.KeyManagementException
-import java.security.NoSuchAlgorithmException
-import javax.net.ssl.SSLContext
@HiltAndroidApp
class MyApplication : LocaleAwareApplication() {
@@ -20,30 +14,4 @@ class MyApplication : LocaleAwareApplication() {
MultiDex.install(this)
}
-
- override
- fun onCreate() {
- super.onCreate()
-
- updateAndroidSecurityProvider()
- }
-
- private fun updateAndroidSecurityProvider() {
- // To fix the following issue, when run app in cellular data, Apis not working
- // javax.net.ssl.SSLHandshakeException: SSL handshake aborted: ssl=0x7edfc49e08: I/O error during system call, Connection reset by peer
- try {
- ProviderInstaller.installIfNeeded(applicationContext)
- val sslContext: SSLContext = SSLContext.getInstance("TLSv1.2")
- sslContext.init(null, null, null)
- sslContext.createSSLEngine()
- } catch (e: GooglePlayServicesRepairableException) {
- e.printStackTrace()
- } catch (e: GooglePlayServicesNotAvailableException) {
- e.printStackTrace()
- } catch (e: NoSuchAlgorithmException) {
- e.printStackTrace()
- } catch (e: KeyManagementException) {
- e.printStackTrace()
- }
- }
}
\ No newline at end of file
diff --git a/appTutorial/build.gradle b/appTutorial/build.gradle
deleted file mode 100644
index c1bc4e3..0000000
--- a/appTutorial/build.gradle
+++ /dev/null
@@ -1,30 +0,0 @@
-plugins {
- id 'com.android.library'
- id 'kotlin-android'
- id 'kotlin-kapt'
-}
-
-android {
- compileSdk 30
-
- defaultConfig {
- minSdk 21
- }
-
- buildTypes {
- release {
- minifyEnabled true
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-
- viewBinding {
- enabled true
- }
-}
-
-dependencies {
- implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0-alpha03"
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1"
- implementation "com.google.android.material:material:1.4.0"
-}
\ No newline at end of file
diff --git a/appTutorial/build.gradle.kts b/appTutorial/build.gradle.kts
new file mode 100644
index 0000000..3f97c7f
--- /dev/null
+++ b/appTutorial/build.gradle.kts
@@ -0,0 +1,42 @@
+plugins {
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.android.kotlin)
+ alias(libs.plugins.kotlin.ksp)
+}
+
+android {
+ namespace = "codes.mina_mikhail.tutorial"
+ compileSdk = 34
+
+ defaultConfig {
+ minSdk = 21
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = true
+ proguardFiles (getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+
+ kotlinOptions {
+ jvmTarget = JavaVersion.VERSION_17.toString()
+ }
+
+
+ buildFeatures {
+ viewBinding = true
+ }
+}
+
+dependencies {
+ implementation(libs.lifecycle)
+ implementation(libs.materialDesign)
+ implementation(libs.coroutinesCore)
+ implementation(libs.coroutinesAndroid)
+}
\ No newline at end of file
diff --git a/appTutorial/proguard-rules.pro b/appTutorial/proguard-rules.pro
index 481bb43..ff59496 100644
--- a/appTutorial/proguard-rules.pro
+++ b/appTutorial/proguard-rules.pro
@@ -1,6 +1,6 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
+# proguardFiles setting in build.gradle.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
diff --git a/appTutorial/src/main/AndroidManifest.xml b/appTutorial/src/main/AndroidManifest.xml
index 69eea33..1d26c87 100644
--- a/appTutorial/src/main/AndroidManifest.xml
+++ b/appTutorial/src/main/AndroidManifest.xml
@@ -1,6 +1,2 @@
-
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/appTutorial/src/main/java/codes/mina_mikhail/app_tutorial/AppTutorialHelper.kt b/appTutorial/src/main/java/codes/mina_mikhail/app_tutorial/AppTutorialHelper.kt
index 94de78c..e8d446d 100644
--- a/appTutorial/src/main/java/codes/mina_mikhail/app_tutorial/AppTutorialHelper.kt
+++ b/appTutorial/src/main/java/codes/mina_mikhail/app_tutorial/AppTutorialHelper.kt
@@ -18,6 +18,7 @@ import androidx.lifecycle.OnLifecycleEvent
import androidx.lifecycle.coroutineScope
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
+import codes.mina_mikhail.tutorial.R
import kotlinx.coroutines.delay
class AppTutorialHelper private constructor(builder: Builder) : LifecycleObserver {
diff --git a/appTutorial/src/main/java/codes/mina_mikhail/app_tutorial/TutorialAdapter.kt b/appTutorial/src/main/java/codes/mina_mikhail/app_tutorial/TutorialAdapter.kt
index 853da64..1711000 100644
--- a/appTutorial/src/main/java/codes/mina_mikhail/app_tutorial/TutorialAdapter.kt
+++ b/appTutorial/src/main/java/codes/mina_mikhail/app_tutorial/TutorialAdapter.kt
@@ -6,7 +6,8 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import codes.mina_mikhail.app_tutorial.TutorialAdapter.ImagesSliderViewHolder
-import codes.mina_mikhail.app_tutorial.databinding.ItemTutorialBinding
+import codes.mina_mikhail.tutorial.R
+import codes.mina_mikhail.tutorial.databinding.ItemTutorialBinding
internal class TutorialAdapter(
private var titleColor: Int,
diff --git a/build.gradle.kts b/build.gradle.kts
index 9d0b2c6..5533e85 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,44 +1,34 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
+import org.jlleitschuh.gradle.ktlint.KtlintExtension
+
+plugins {
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.android.library) apply false
+ alias(libs.plugins.android.kotlin) apply false
+ alias(libs.plugins.kotlin.ksp) apply false
+ alias(libs.plugins.kotlin.jvm) apply false
+ alias(libs.plugins.navigation.safeargs) apply false
+ alias(libs.plugins.ktlint) apply false
+ alias(libs.plugins.dagger.hilt.android) apply false
+ alias(libs.plugins.googleServices) apply false
+}
+
buildscript {
- repositories {
- google()
- mavenCentral()
- }
dependencies {
- classpath(Config.Dependencies.gradleVersion)
- classpath(Config.Dependencies.kotlin)
- classpath(Config.Dependencies.navigationSafeArgs)
- classpath(Config.Dependencies.hilt)
+ classpath(libs.navigationSafeArgs)
}
}
-plugins {
- id(Config.Plugins.ktLint) version Versions.ktLint
-}
-
subprojects {
- apply(plugin = Config.Plugins.ktLint) // To apply ktLint to all included modules
-
- repositories {
- mavenCentral()
- }
+ apply(plugin = "org.jlleitschuh.gradle.ktlint") // To apply ktLint to all included modules
- configure {
+ configure {
debug.set(true)
}
}
-allprojects {
- repositories {
- google()
- mavenCentral()
- jcenter()
- maven(url = Config.Dependencies.jitPackURL)
- }
-}
tasks.register("clean", Delete::class) {
- delete(rootProject.buildDir)
+ delete(rootProject.layout.buildDirectory)
}
tasks.register("installGitHooks", Copy::class) {
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
deleted file mode 100644
index 56d089c..0000000
--- a/buildSrc/build.gradle.kts
+++ /dev/null
@@ -1,9 +0,0 @@
-plugins {
- `kotlin-dsl`
-}
-
-repositories {
- google()
- mavenCentral()
- jcenter()
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/java/Config.kt b/buildSrc/src/main/java/Config.kt
deleted file mode 100644
index 79d92ab..0000000
--- a/buildSrc/src/main/java/Config.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-object Config {
- object AppConfig {
- const val appId = "com.mina_mikhail.base_mvvm"
- const val compileSdkVersion = 30
- const val minSdkVersion = 21
- const val versionCode = 1
- const val versionName = "1"
- const val testRunner = "androidx.test.runner.AndroidJUnitRunner"
- }
-
- object Dependencies {
- const val jitPackURL = "https://jitpack.io"
- const val gradleVersion = "com.android.tools.build:gradle:${Versions.gradleVersion}"
- const val kotlin = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}"
- const val navigationSafeArgs =
- "androidx.navigation:navigation-safe-args-gradle-plugin:${Versions.androidNavigation}"
- const val hilt = "com.google.dagger:hilt-android-gradle-plugin:${Versions.hiltVersion}"
- }
-
- object Plugins {
- const val androidApplication = "com.android.application"
- const val kotlinAndroid = "kotlin-android"
- const val kotlinKapt = "kotlin-kapt"
- const val navigationSafeArgs = "androidx.navigation.safeargs"
- const val hilt = "dagger.hilt.android.plugin"
- const val androidLibrary = "com.android.library"
- const val kotlinJvm = "org.jetbrains.kotlin.jvm"
- const val ktLint = "org.jlleitschuh.gradle.ktlint"
- }
-
- object Modules {
- const val domain = ":domain"
- const val data = ":data"
- const val presentation = ":presentation"
- const val prettyPopUp = ":prettyPopUp"
- const val actionChooser = ":actionChooser"
- const val appTutorial = ":appTutorial"
- const val imagesSlider = ":imagesSlider"
- }
-
- object Environments {
- const val debugBaseUrl = "\"http://url.to.server/api/\""
- const val releaseBaseUrl = "\"http://url.to.server/api/\""
- }
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/java/Libraries.kt b/buildSrc/src/main/java/Libraries.kt
deleted file mode 100644
index 3a87859..0000000
--- a/buildSrc/src/main/java/Libraries.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-object Libraries {
-
- // Support
- const val appCompat = "androidx.appcompat:appcompat:${Versions.appcompat}"
- const val coreKtx = "androidx.core:core-ktx:${Versions.coreKtx}"
- const val androidSupport = "androidx.legacy:legacy-support-v4:${Versions.supportVersion}"
-
- // Kotlin
- const val kotlin = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${Versions.kotlin}"
-
- // Java
- const val javaInject = "javax.inject:javax.inject:${Versions.javaInject}"
-
- // Arch Components
- const val viewModel = "androidx.lifecycle:lifecycle-viewmodel-ktx:${Versions.lifecycle}"
- const val lifeData = "androidx.lifecycle:lifecycle-livedata-ktx:${Versions.lifecycle}"
- const val lifecycle = "androidx.lifecycle:lifecycle-runtime-ktx:${Versions.lifecycle}"
- const val viewModelState = "androidx.lifecycle:lifecycle-viewmodel-savedstate:${Versions.lifecycle}"
-
- // Kotlin Coroutines
- const val coroutinesCore = "org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.kotlinCoroutines}"
- const val coroutinesAndroid =
- "org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.kotlinCoroutines}"
-
- // Networking
- const val retrofit = "com.squareup.retrofit2:retrofit:${Versions.retrofit}"
- const val retrofitConverter = "com.squareup.retrofit2:converter-gson:${Versions.retrofit}"
- const val gson = "com.google.code.gson:gson:${Versions.gson}"
- const val interceptor = "com.squareup.okhttp3:logging-interceptor:${Versions.interceptor}"
- const val chuckLogging = "com.readystatesoftware.chuck:library:${Versions.chuckLogging}"
-
- // UI
- const val materialDesign = "com.google.android.material:material:${Versions.materialDesign}"
- const val navigationFragment = "androidx.navigation:navigation-fragment-ktx:${Versions.androidNavigation}"
- const val navigationUI = "androidx.navigation:navigation-ui-ktx:${Versions.androidNavigation}"
- const val loadingAnimations = "com.github.ybq:Android-SpinKit:${Versions.loadingAnimations}"
- const val alerter = "com.github.tapadoo:alerter:${Versions.alerter}"
- const val coil = "io.coil-kt:coil:${Versions.coil}"
-
- // Utils
- const val playServices = "com.google.android.gms:play-services-auth:${Versions.playServices}"
- const val localization = "com.zeugmasolutions.localehelper:locale-helper-android:${Versions.localization}"
- const val multidex = "androidx.multidex:multidex:${Versions.multidex}"
- const val permissions = "com.afollestad.assent:core:${Versions.permissions}"
-
- // Hilt
- const val hilt = "com.google.dagger:hilt-android:${Versions.hiltVersion}"
- const val hiltDaggerCompiler = "com.google.dagger:hilt-android-compiler:${Versions.hiltVersion}"
-
- // Map
- const val map = "com.google.android.gms:play-services-maps:${Versions.map}"
- const val playServicesLocation =
- "com.google.android.gms:play-services-location:${Versions.playServicesLocation}"
- const val rxLocation = "com.github.ShabanKamell:RxLocation:${Versions.rxLocation}"
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/java/Versions.kt b/buildSrc/src/main/java/Versions.kt
deleted file mode 100644
index f0563a9..0000000
--- a/buildSrc/src/main/java/Versions.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-object Versions {
- const val gradleVersion = "7.0.2"
- const val kotlin = "1.5.21"
- const val ktLint = "10.2.0"
-
- // Java Inject
- const val javaInject = "1"
-
- // Support
- const val appcompat = "1.3.1"
- const val coreKtx = "1.6.0"
- const val supportVersion = "1.0.0"
-
- // Arch Components
- const val lifecycle = "2.4.0-alpha03"
-
- // Kotlin Coroutines
- const val kotlinCoroutines = "1.4.1"
-
- // Networking
- const val retrofit = "2.9.0"
- const val gson = "2.8.6"
- const val interceptor = "4.8.1"
- const val chuckLogging = "1.1.0"
-
- // UI
- const val materialDesign = "1.4.0"
- const val androidNavigation = "2.3.5"
- const val loadingAnimations = "1.4.0"
- const val alerter = "7.2.4"
- const val coil = "1.3.2"
-
- // Utils
- const val playServices = "19.2.0"
- const val localization = "1.1.4"
- const val multidex = "2.0.1"
- const val permissions = "3.0.0-RC4"
-
- // Hilt
- const val hiltVersion = "2.38.1"
-
- // Map
- const val map = "17.0.1"
- const val playServicesLocation = "18.0.0"
- const val rxLocation = "1.0"
-}
\ No newline at end of file
diff --git a/data/build.gradle.kts b/data/build.gradle.kts
index 868ae7d..7a2e8a3 100644
--- a/data/build.gradle.kts
+++ b/data/build.gradle.kts
@@ -1,36 +1,46 @@
plugins {
- id(Config.Plugins.androidLibrary)
- id(Config.Plugins.kotlinAndroid)
- id(Config.Plugins.kotlinKapt)
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.android.kotlin)
+ alias(libs.plugins.kotlin.ksp)
}
android {
- compileSdk = Config.AppConfig.compileSdkVersion
+ namespace = "com.mina_mikhail.base_mvvm.data"
+ compileSdk = 34
defaultConfig {
- minSdk = Config.AppConfig.minSdkVersion
- targetSdk = Config.AppConfig.compileSdkVersion
+ minSdk = 21
}
+
buildTypes {
- getByName("release") {
+ release {
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
}
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+
+ kotlinOptions {
+ jvmTarget = JavaVersion.VERSION_17.toString()
+ }
+
}
dependencies {
// Kotlin Coroutines
- implementation(Libraries.coroutinesCore)
- implementation(Libraries.coroutinesAndroid)
+ implementation(libs.coroutinesCore)
+ implementation(libs.coroutinesAndroid)
// Networking
- implementation(Libraries.retrofit)
- implementation(Libraries.gson)
+ implementation(libs.bundles.networking)
- implementation(Libraries.javaInject)
+ implementation(libs.javaInject)
// Project Modules
- implementation(project(Config.Modules.domain))
+ implementation(projects.domain)
}
\ No newline at end of file
diff --git a/data/src/main/AndroidManifest.xml b/data/src/main/AndroidManifest.xml
index c47c7e2..1d26c87 100644
--- a/data/src/main/AndroidManifest.xml
+++ b/data/src/main/AndroidManifest.xml
@@ -1,2 +1,2 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts
index 8e2b3f0..59be345 100644
--- a/domain/build.gradle.kts
+++ b/domain/build.gradle.kts
@@ -1,16 +1,16 @@
plugins {
- id(Config.Plugins.kotlinJvm)
+ alias(libs.plugins.kotlin.jvm)
}
java {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
}
dependencies {
// Kotlin Coroutines
- implementation(Libraries.coroutinesCore)
- implementation(Libraries.coroutinesAndroid)
+ implementation(libs.coroutinesCore)
+ implementation(libs.coroutinesAndroid)
- implementation(Libraries.javaInject)
+ implementation(libs.javaInject)
}
\ No newline at end of file
diff --git a/domain/src/main/java/com/mina_mikhail/base_mvvm/domain/utils/Resource.kt b/domain/src/main/java/com/mina_mikhail/base_mvvm/domain/utils/Resource.kt
index 8ab3e5f..93896b9 100644
--- a/domain/src/main/java/com/mina_mikhail/base_mvvm/domain/utils/Resource.kt
+++ b/domain/src/main/java/com/mina_mikhail/base_mvvm/domain/utils/Resource.kt
@@ -10,7 +10,7 @@ sealed class Resource {
val message: String? = null
) : Resource()
- object Loading : Resource()
+ data object Loading : Resource()
- object Default : Resource()
+ data object Default : Resource()
}
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
new file mode 100644
index 0000000..f48153f
--- /dev/null
+++ b/gradle/libs.versions.toml
@@ -0,0 +1,115 @@
+[versions]
+gradleVersion = "8.5.0"
+kotlin = "2.0.0"
+ktLint = "11.5.1"
+javaInject = "1"
+appcompat = "1.7.0"
+coreKtx = "1.13.1"
+supportVersion = "1.0.0"
+lifecycle = "2.8.2"
+kotlinCoroutines = "1.7.3"
+retrofit = "2.9.0"
+gson = "2.10.1"
+interceptor = "4.10.0"
+chuckLogging = "1.1.0"
+materialDesign = "1.12.0"
+androidNavigation = "2.7.7"
+loadingAnimations = "1.4.0"
+alerter = "7.2.4"
+coil = "2.4.0"
+gms-googleServices = "4.4.2"
+playServices = "21.2.0"
+localization = "1.5.1"
+multidex = "2.0.1"
+permissions = "3.0.0-RC4"
+hiltVersion = "2.51.1"
+map = "18.2.0"
+playServicesLocation = "21.3.0"
+ksp = "2.0.0-1.0.21"
+glide = "4.15.1"
+swiperefreshlayout = "1.1.0"
+photoView = "2.3.0"
+
+[libraries]
+
+# Support
+appCompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat"}
+coreKtx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx"}
+androidSupport = { group = "androidx.legacy", name = "legacy-support-v4", version.ref = "supportVersion"}
+androidSwiperefreshlayout = { group = "androidx.swiperefreshlayout", name = "swiperefreshlayout", version.ref = "swiperefreshlayout" }
+# Kotlin
+kotlin = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk8", version.ref = "kotlin" }
+
+# Java
+javaInject = { group = "javax.inject", name = "javax.inject", version.ref = "javaInject" }
+
+# Arch Components
+viewModel = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycle" }
+lifeData = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycle" }
+lifecycle = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" }
+viewModelState = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-savedstate", version.ref = "lifecycle" }
+
+# Coroutines
+coroutinesCore = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinCoroutines" }
+coroutinesAndroid = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinCoroutines" }
+
+
+# Networking
+retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
+retrofitConverter = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" }
+gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
+interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "interceptor" }
+chuckLogging = { group = "com.readystatesoftware.chuck", name = "library", version.ref = "chuckLogging" }
+
+# UI
+materialDesign = { group = "com.google.android.material", name = "material", version.ref = "materialDesign" }
+navigationSafeArgs = {group = "androidx.navigation",name = "navigation-safe-args-gradle-plugin", version.ref = "androidNavigation"}
+navigationFragment = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "androidNavigation" }
+navigationUI = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "androidNavigation" }
+loadingAnimations = { group = "com.github.ybq", name = "Android-SpinKit", version.ref = "loadingAnimations" }
+alerter = { group = "com.github.tapadoo", name = "alerter", version.ref = "alerter" }
+coil = { group = "io.coil-kt", name = "coil", version.ref = "coil" }
+
+# Utils
+playServices = { group = "com.google.android.gms", name = "play-services-auth", version.ref = "playServices" }
+localization = { group = "com.zeugmasolutions.localehelper", name = "locale-helper-android", version.ref = "localization" }
+multidex = { group = "androidx.multidex", name = "multidex", version.ref = "multidex" }
+permissions = { group = "com.afollestad.assent", name = "core", version.ref = "permissions" }
+glide = { group = "com.github.bumptech.glide", name = "glide", version.ref = "glide"}
+glideCompiler = { group = "com.github.bumptech.glide", name = "ksp", version.ref = "glide"}
+photoView = { group = "com.github.chrisbanes", name = "PhotoView", version.ref = "photoView"}
+
+# Hilt
+hilt = { group = "com.google.dagger", name = "hilt-android", version.ref = "hiltVersion" }
+hiltDaggerCompiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hiltVersion" }
+
+# Maps
+map = { group = "com.google.android.gms", name = "play-services-maps", version.ref = "map" }
+playServicesLocation = { group = "com.google.android.gms", name = "play-services-location", version.ref = "playServicesLocation" }
+
+[bundles]
+
+networking = [
+ "retrofit","retrofitConverter","gson","interceptor","chuckLogging"
+]
+
+androidSupport = [
+ "appCompat","coreKtx","androidSupport"
+]
+
+archComponents = [ "viewModel","lifecycle","lifeData","viewModelState",
+ "materialDesign","navigationFragment","navigationUI"
+]
+
+
+[plugins]
+android-library = { id = "com.android.library", version.ref = "gradleVersion" }
+android-application = { id = "com.android.application", version.ref = "gradleVersion"}
+android-kotlin = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin"}
+kotlin-ksp = { id = "com.google.devtools.ksp", version.ref = "ksp"}
+kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin"}
+navigation-safeargs = { id = "androidx.navigation.safeargs", version.ref = "androidNavigation" }
+dagger-hilt-android = { id = "com.google.dagger.hilt.android" , version.ref = "hiltVersion" }
+ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktLint" }
+googleServices = { id = "com.google.gms.google-services", version.ref = "gms-googleServices"}
+
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 6974aba..5815001 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Sat Aug 14 00:33:07 EET 2021
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
diff --git a/imagesSlider/build.gradle b/imagesSlider/build.gradle
deleted file mode 100644
index b8a1ef2..0000000
--- a/imagesSlider/build.gradle
+++ /dev/null
@@ -1,34 +0,0 @@
-plugins {
- id 'com.android.library'
- id 'kotlin-android'
- id 'kotlin-kapt'
-}
-
-android {
- compileSdk 30
-
- defaultConfig {
- minSdk 21
- }
-
- buildTypes {
- release {
- minifyEnabled true
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-
- viewBinding {
- enabled true
- }
-}
-
-dependencies {
- implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0-alpha03"
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1"
- implementation "com.google.android.material:material:1.4.0"
- implementation "com.github.chrisbanes:PhotoView:2.3.0"
- implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
- implementation "com.github.bumptech.glide:glide:4.12.0"
- kapt "com.github.bumptech.glide:compiler:4.12.0"
-}
\ No newline at end of file
diff --git a/imagesSlider/build.gradle.kts b/imagesSlider/build.gradle.kts
new file mode 100644
index 0000000..0d41e43
--- /dev/null
+++ b/imagesSlider/build.gradle.kts
@@ -0,0 +1,45 @@
+plugins {
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.android.kotlin)
+ alias(libs.plugins.kotlin.ksp)
+}
+
+android {
+ namespace = "codes.mina_mikhail.images_slider"
+ compileSdk = 34
+
+ defaultConfig {
+ minSdk = 21
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = true
+ proguardFiles (getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+
+ kotlinOptions {
+ jvmTarget = JavaVersion.VERSION_17.toString()
+ }
+
+
+ buildFeatures {
+ viewBinding = true
+ }
+}
+
+dependencies {
+ implementation(libs.lifecycle)
+ implementation(libs.materialDesign)
+ implementation(libs.coroutinesCore)
+ implementation(libs.photoView)
+ implementation(libs.androidSwiperefreshlayout)
+ implementation(libs.glide)
+ ksp(libs.glideCompiler)
+}
\ No newline at end of file
diff --git a/imagesSlider/proguard-rules.pro b/imagesSlider/proguard-rules.pro
index a8c234f..9fc645c 100644
--- a/imagesSlider/proguard-rules.pro
+++ b/imagesSlider/proguard-rules.pro
@@ -1,6 +1,6 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
+# proguardFiles setting in build.gradle.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
diff --git a/imagesSlider/src/main/AndroidManifest.xml b/imagesSlider/src/main/AndroidManifest.xml
index ef5d7fa..1681dd4 100644
--- a/imagesSlider/src/main/AndroidManifest.xml
+++ b/imagesSlider/src/main/AndroidManifest.xml
@@ -1,6 +1,5 @@
-
+
diff --git a/presentation/build.gradle.kts b/presentation/build.gradle.kts
index 412b501..6609e5f 100644
--- a/presentation/build.gradle.kts
+++ b/presentation/build.gradle.kts
@@ -1,75 +1,76 @@
plugins {
- id(Config.Plugins.androidLibrary)
- id(Config.Plugins.kotlinAndroid)
- id(Config.Plugins.kotlinKapt)
- id(Config.Plugins.hilt)
- id(Config.Plugins.navigationSafeArgs)
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.android.kotlin)
+ alias(libs.plugins.kotlin.ksp)
+ alias(libs.plugins.dagger.hilt.android)
+ alias(libs.plugins.navigation.safeargs)
}
android {
- compileSdk = Config.AppConfig.compileSdkVersion
+ namespace = "com.mina_mikhail.base_mvvm.presentation"
+ compileSdk = 34
defaultConfig {
- minSdk = Config.AppConfig.minSdkVersion
+ minSdk = 21
vectorDrawables.useSupportLibrary = true
}
buildTypes {
- getByName("release") {
+ release{
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
}
- dataBinding {
- isEnabled = true
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+
+ kotlinOptions {
+ jvmTarget = JavaVersion.VERSION_17.toString()
+ }
+
+ buildFeatures {
+ dataBinding = true
}
}
dependencies {
// Support
- implementation(Libraries.appCompat)
- implementation(Libraries.coreKtx)
- implementation(Libraries.androidSupport)
+ implementation(libs.bundles.androidSupport)
// Arch Components
- implementation(Libraries.viewModel)
- implementation(Libraries.lifeData)
- implementation(Libraries.lifecycle)
- implementation(Libraries.viewModelState)
+ implementation(libs.bundles.archComponents)
// Kotlin Coroutines
- implementation(Libraries.coroutinesCore)
- implementation(Libraries.coroutinesAndroid)
+ implementation(libs.coroutinesCore)
+ implementation(libs.coroutinesAndroid)
// UI
- implementation(Libraries.materialDesign)
- implementation(Libraries.navigationFragment)
- implementation(Libraries.navigationUI)
- implementation(Libraries.loadingAnimations)
- implementation(Libraries.alerter)
- implementation(Libraries.coil)
+ implementation(libs.loadingAnimations)
+ implementation(libs.alerter)
+ implementation(libs.coil)
// Utils
- implementation(Libraries.playServices)
- implementation(Libraries.localization)
- implementation(Libraries.permissions)
- implementation(Libraries.gson)
+ implementation(libs.playServices)
+ implementation(libs.localization)
+ implementation(libs.permissions)
+ implementation(libs.gson)
// Hilt
- implementation(Libraries.hilt)
- kapt(Libraries.hiltDaggerCompiler)
+ implementation(libs.hilt)
+ ksp(libs.hiltDaggerCompiler)
// Map
- implementation(Libraries.map)
- implementation(Libraries.playServicesLocation)
- implementation(Libraries.rxLocation)
+ implementation(libs.map)
+ implementation(libs.playServicesLocation)
// Project Modules
- implementation(project(Config.Modules.domain))
- implementation(project(Config.Modules.prettyPopUp))
- implementation(project(Config.Modules.actionChooser))
- implementation(project(Config.Modules.appTutorial))
- implementation(project(Config.Modules.imagesSlider))
+ implementation(projects.domain)
+ implementation(projects.prettyPopUp)
+ implementation(projects.actionChooser)
+ implementation(projects.appTutorial)
+ implementation(projects.imagesSlider)
}
\ No newline at end of file
diff --git a/presentation/src/main/AndroidManifest.xml b/presentation/src/main/AndroidManifest.xml
index f31fd20..4685f82 100644
--- a/presentation/src/main/AndroidManifest.xml
+++ b/presentation/src/main/AndroidManifest.xml
@@ -1,6 +1,5 @@
-
+
diff --git a/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/account/AccountFragment.kt b/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/account/AccountFragment.kt
index 6a379f1..23359bd 100644
--- a/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/account/AccountFragment.kt
+++ b/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/account/AccountFragment.kt
@@ -83,6 +83,8 @@ class AccountFragment : BaseFragment() {
hideLoading()
handleApiError(it)
}
+
+ else -> {}
}
}
}
diff --git a/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/auth/log_in/LogInFragment.kt b/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/auth/log_in/LogInFragment.kt
index 86f857f..5fb1b58 100644
--- a/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/auth/log_in/LogInFragment.kt
+++ b/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/auth/log_in/LogInFragment.kt
@@ -158,6 +158,8 @@ class LogInFragment : BaseFragment() {
hideLoading()
handleApiError(it, retryAction = { viewModel.onLogInClicked() })
}
+
+ else -> {}
}
}
}
diff --git a/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/base/BaseActivity.kt b/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/base/BaseActivity.kt
index d56b85d..1786feb 100644
--- a/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/base/BaseActivity.kt
+++ b/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/base/BaseActivity.kt
@@ -7,7 +7,6 @@ import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
-import androidx.lifecycle.LiveData
import androidx.navigation.NavController
import com.zeugmasolutions.localehelper.LocaleHelper
import com.zeugmasolutions.localehelper.LocaleHelperActivityDelegate
@@ -16,54 +15,40 @@ import java.util.Locale
abstract class BaseActivity : AppCompatActivity() {
- private val localeDelegate: LocaleHelperActivityDelegate = LocaleHelperActivityDelegateImpl()
+ private val localeDelegate: LocaleHelperActivityDelegate by lazy {
+ LocaleHelperActivityDelegateImpl()
+ }
private var _binding: VB? = null
- open val binding get() = _binding!!
- public lateinit var navController: LiveData
+ open val binding get() = checkNotNull(_binding)
+ public lateinit var navController: NavController
- override
- fun createConfigurationContext(overrideConfiguration: Configuration): Context {
+ override fun createConfigurationContext(overrideConfiguration: Configuration): Context {
val context = super.createConfigurationContext(overrideConfiguration)
return LocaleHelper.onAttach(context)
}
- override
- fun getApplicationContext(): Context =
+ override fun getApplicationContext(): Context =
localeDelegate.getApplicationContext(super.getApplicationContext())
- override
- fun onResume() {
+ override fun onResume() {
super.onResume()
localeDelegate.onResumed(this)
}
- override
- fun onPause() {
+ override fun onPause() {
super.onPause()
localeDelegate.onPaused()
}
- override
- fun onCreate(savedInstanceState: Bundle?) {
+ override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initViewBinding()
setContentView(binding.root)
- if (savedInstanceState == null) {
- setUpBottomNavigation()
- }
-
setUpViews()
}
- override
- fun onRestoreInstanceState(savedInstanceState: Bundle) {
- super.onRestoreInstanceState(savedInstanceState)
-
- setUpBottomNavigation()
- }
-
private fun initViewBinding() {
_binding = DataBindingUtil.setContentView(this, getLayoutId())
binding.lifecycleOwner = this
@@ -73,19 +58,15 @@ abstract class BaseActivity : AppCompatActivity() {
@LayoutRes
abstract fun getLayoutId(): Int
- open fun setUpBottomNavigation() {}
-
open fun setUpViews() {}
open fun updateLocale(language: String) {
localeDelegate.setLocale(this, Locale(language))
}
- override
- fun onSupportNavigateUp(): Boolean {
- return navController.value?.navigateUp()!! || super.onSupportNavigateUp()
+ override fun onSupportNavigateUp(): Boolean {
+ return navController.navigateUp() || super.onSupportNavigateUp()
}
- override
- fun getDelegate() = localeDelegate.getAppCompatDelegate(super.getDelegate())
+ override fun getDelegate() = localeDelegate.getAppCompatDelegate(super.getDelegate())
}
\ No newline at end of file
diff --git a/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/base/extensions/NavigationExtensions.kt b/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/base/extensions/NavigationExtensions.kt
deleted file mode 100644
index bf00923..0000000
--- a/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/base/extensions/NavigationExtensions.kt
+++ /dev/null
@@ -1,238 +0,0 @@
-package com.mina_mikhail.base_mvvm.presentation.base.extensions
-
-import android.content.Intent
-import android.util.SparseArray
-import androidx.core.util.forEach
-import androidx.core.util.set
-import androidx.fragment.app.FragmentManager
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import androidx.navigation.NavController
-import androidx.navigation.fragment.NavHostFragment
-import com.google.android.material.bottomnavigation.BottomNavigationView
-import com.mina_mikhail.base_mvvm.presentation.R
-
-/**
- * Manages the various graphs needed for a [BottomNavigationView].
- *
- * This sample is a workaround until the Navigation Component supports multiple back stacks.
- */
-fun BottomNavigationView.setupWithNavController(
- navGraphIds: List,
- fragmentManager: FragmentManager,
- containerId: Int,
- intent: Intent
-): LiveData {
-
- // Map of tags
- val graphIdToTagMap = SparseArray()
- // Result. Mutable live data with the selected controlled
- val selectedNavController = MutableLiveData()
-
- var firstFragmentGraphId = 0
-
- // First create a NavHostFragment for each NavGraph ID
- navGraphIds.forEachIndexed { index, navGraphId ->
- val fragmentTag = getFragmentTag(index)
-
- // Find or create the Navigation host fragment
- val navHostFragment = obtainNavHostFragment(
- fragmentManager,
- fragmentTag,
- navGraphId,
- containerId
- )
-
- // Obtain its id
- val graphId = navHostFragment.navController.graph.id
-
- if (index == 0) {
- firstFragmentGraphId = graphId
- }
-
- // Save to the map
- graphIdToTagMap[graphId] = fragmentTag
-
- // Attach or detach nav host fragment depending on whether it's the selected item.
- if (this.selectedItemId == graphId) {
- // Update livedata with the selected graph
- selectedNavController.value = navHostFragment.navController
- attachNavHostFragment(fragmentManager, navHostFragment, index == 0)
- } else {
- detachNavHostFragment(fragmentManager, navHostFragment)
- }
- }
-
- // Now connect selecting an item with swapping Fragments
- var selectedItemTag = graphIdToTagMap[this.selectedItemId]
- val firstFragmentTag = graphIdToTagMap[firstFragmentGraphId]
- var isOnFirstFragment = selectedItemTag == firstFragmentTag
-
- // When a navigation item is selected
- setOnNavigationItemSelectedListener { item ->
- // Don't do anything if the state is state has already been saved.
- if (fragmentManager.isStateSaved) {
- false
- } else {
- val newlySelectedItemTag = graphIdToTagMap[item.itemId]
- if (selectedItemTag != newlySelectedItemTag) {
- // Pop everything above the first fragment (the "fixed start destination")
- fragmentManager.popBackStack(
- firstFragmentTag,
- FragmentManager.POP_BACK_STACK_INCLUSIVE
- )
- val selectedFragment = fragmentManager.findFragmentByTag(newlySelectedItemTag)
- as NavHostFragment
-
- // Exclude the first fragment tag because it's always in the back stack.
- if (firstFragmentTag != newlySelectedItemTag) {
- // Commit a transaction that cleans the back stack and adds the first fragment
- // to it, creating the fixed started destination.
- fragmentManager.beginTransaction()
- .setCustomAnimations(
- R.anim.nav_default_enter_anim,
- R.anim.nav_default_exit_anim,
- R.anim.nav_default_pop_enter_anim,
- R.anim.nav_default_pop_exit_anim
- )
- .attach(selectedFragment)
- .setPrimaryNavigationFragment(selectedFragment)
- .apply {
- // Detach all other Fragments
- graphIdToTagMap.forEach { _, fragmentTagIter ->
- if (fragmentTagIter != newlySelectedItemTag) {
- detach(fragmentManager.findFragmentByTag(firstFragmentTag)!!)
- }
- }
- }
- .addToBackStack(firstFragmentTag)
- .setReorderingAllowed(true)
- .commit()
- }
- selectedItemTag = newlySelectedItemTag
- isOnFirstFragment = selectedItemTag == firstFragmentTag
- selectedNavController.value = selectedFragment.navController
- true
- } else {
- false
- }
- }
- }
-
- // Optional: on item reselected, pop back stack to the destination of the graph
- setupItemReselected(graphIdToTagMap, fragmentManager)
-
- // Handle deep link
- setupDeepLinks(navGraphIds, fragmentManager, containerId, intent)
-
- // Finally, ensure that we update our BottomNavigationView when the back stack changes
- fragmentManager.addOnBackStackChangedListener {
- if (!isOnFirstFragment && !fragmentManager.isOnBackStack(firstFragmentTag)) {
- this.selectedItemId = firstFragmentGraphId
- }
-
- // Reset the graph if the currentDestination is not valid (happens when the back
- // stack is popped after using the back button).
- selectedNavController.value?.let { controller ->
- if (controller.currentDestination == null) {
- controller.navigate(controller.graph.id)
- }
- }
- }
- return selectedNavController
-}
-
-private fun BottomNavigationView.setupDeepLinks(
- navGraphIds: List,
- fragmentManager: FragmentManager,
- containerId: Int,
- intent: Intent
-) {
- navGraphIds.forEachIndexed { index, navGraphId ->
- val fragmentTag = getFragmentTag(index)
-
- // Find or create the Navigation host fragment
- val navHostFragment = obtainNavHostFragment(
- fragmentManager,
- fragmentTag,
- navGraphId,
- containerId
- )
- // Handle Intent
- if (navHostFragment.navController.handleDeepLink(intent) &&
- selectedItemId != navHostFragment.navController.graph.id
- ) {
- this.selectedItemId = navHostFragment.navController.graph.id
- }
- }
-}
-
-private fun BottomNavigationView.setupItemReselected(
- graphIdToTagMap: SparseArray,
- fragmentManager: FragmentManager
-) {
- setOnNavigationItemReselectedListener { item ->
- val newlySelectedItemTag = graphIdToTagMap[item.itemId]
- val selectedFragment = fragmentManager.findFragmentByTag(newlySelectedItemTag)
- as NavHostFragment
- val navController = selectedFragment.navController
- // Pop the back stack to the start destination of the current navController graph
- navController.popBackStack(
- navController.graph.startDestination, false
- )
- }
-}
-
-private fun detachNavHostFragment(
- fragmentManager: FragmentManager,
- navHostFragment: NavHostFragment
-) {
- fragmentManager.beginTransaction()
- .detach(navHostFragment)
- .commitNow()
-}
-
-private fun attachNavHostFragment(
- fragmentManager: FragmentManager,
- navHostFragment: NavHostFragment,
- isPrimaryNavFragment: Boolean
-) {
- fragmentManager.beginTransaction()
- .attach(navHostFragment)
- .apply {
- if (isPrimaryNavFragment) {
- setPrimaryNavigationFragment(navHostFragment)
- }
- }
- .commitNow()
-}
-
-private fun obtainNavHostFragment(
- fragmentManager: FragmentManager,
- fragmentTag: String,
- navGraphId: Int,
- containerId: Int
-): NavHostFragment {
- // If the Nav Host fragment exists, return it
- val existingFragment = fragmentManager.findFragmentByTag(fragmentTag) as NavHostFragment?
- existingFragment?.let { return it }
-
- // Otherwise, create it and return it.
- val navHostFragment = NavHostFragment.create(navGraphId)
- fragmentManager.beginTransaction()
- .add(containerId, navHostFragment, fragmentTag)
- .commitNow()
- return navHostFragment
-}
-
-private fun FragmentManager.isOnBackStack(backStackName: String): Boolean {
- val backStackCount = backStackEntryCount
- for (index in 0 until backStackCount) {
- if (getBackStackEntryAt(index).name == backStackName) {
- return true
- }
- }
- return false
-}
-
-private fun getFragmentTag(index: Int) = "bottomNavigation#$index"
\ No newline at end of file
diff --git a/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/base/extensions/ViewExtensions.kt b/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/base/extensions/ViewExtensions.kt
index 1e5c820..dda1d10 100644
--- a/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/base/extensions/ViewExtensions.kt
+++ b/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/base/extensions/ViewExtensions.kt
@@ -10,7 +10,6 @@ import android.widget.ProgressBar
import androidx.annotation.ColorRes
import androidx.constraintlayout.widget.Group
import androidx.core.content.ContextCompat
-import androidx.databinding.BindingAdapter
import coil.ImageLoader
import coil.load
import coil.request.ImageRequest
@@ -46,7 +45,6 @@ fun View.invisible() {
}
}
-@BindingAdapter("app:goneUnless")
fun View.goneUnless(visible: Boolean) {
visibility = if (visible) View.VISIBLE else View.GONE
if (this is Group) {
@@ -93,7 +91,6 @@ fun View.showSnackBar(message: String, retryActionName: String? = null, action:
snackBar.show()
}
-@BindingAdapter(value = ["app:loadImage", "app:progressBar"], requireAll = false)
fun ImageView.loadImage(imageUrl: String?, progressBar: ProgressBar?) {
if (imageUrl != null && imageUrl.isNotEmpty()) {
val request = ImageRequest.Builder(context)
@@ -112,7 +109,7 @@ fun ImageView.loadImage(imageUrl: String?, progressBar: ProgressBar?) {
setImageDrawable(result)
}
)
- .listener(onError = { request: ImageRequest, _: Throwable ->
+ .listener(onError = { request, _ ->
progressBar?.hide()
setImageDrawable(request.error)
})
@@ -126,9 +123,8 @@ fun ImageView.loadImage(imageUrl: String?, progressBar: ProgressBar?) {
}
}
-@BindingAdapter(value = ["app:loadCircleImage", "app:progressBar"], requireAll = false)
fun ImageView.loadCircleImage(imageUrl: String?, progressBar: ProgressBar?) {
- if (imageUrl != null && imageUrl.isNotEmpty()) {
+ if (!imageUrl.isNullOrEmpty()) {
val request = ImageRequest.Builder(context)
.data(imageUrl)
.crossfade(true)
@@ -148,7 +144,7 @@ fun ImageView.loadCircleImage(imageUrl: String?, progressBar: ProgressBar?) {
setImageDrawable(result)
}
)
- .listener(onError = { request: ImageRequest, _: Throwable ->
+ .listener(onError = { request, _ ->
progressBar?.hide()
setImageDrawable(request.error)
})
@@ -167,9 +163,8 @@ fun ImageView.loadCircleImage(imageUrl: String?, progressBar: ProgressBar?) {
}
}
-@BindingAdapter(value = ["app:loadRoundImage", "app:progressBar"], requireAll = false)
fun ImageView.loadRoundImage(imageUrl: String?, progressBar: ProgressBar?) {
- if (imageUrl != null && imageUrl.isNotEmpty()) {
+ if (!imageUrl.isNullOrEmpty()) {
val request = ImageRequest.Builder(context)
.data(imageUrl)
.crossfade(true)
@@ -191,7 +186,7 @@ fun ImageView.loadRoundImage(imageUrl: String?, progressBar: ProgressBar?) {
setImageDrawable(result)
}
)
- .listener(onError = { request: ImageRequest, _: Throwable ->
+ .listener(onError = { request, _ ->
progressBar?.hide()
setImageDrawable(request.error)
})
@@ -212,7 +207,6 @@ fun ImageView.loadRoundImage(imageUrl: String?, progressBar: ProgressBar?) {
}
}
-@BindingAdapter("load_drawable")
fun loadDrawable(imageView: ImageView, drawable: Drawable?) {
imageView.setImageDrawable(drawable)
}
\ No newline at end of file
diff --git a/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/home/HomeActivity.kt b/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/home/HomeActivity.kt
index 9a42c75..6188d2a 100644
--- a/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/home/HomeActivity.kt
+++ b/presentation/src/main/java/com/mina_mikhail/base_mvvm/presentation/home/HomeActivity.kt
@@ -6,9 +6,12 @@ import android.content.Intent
import android.content.IntentFilter
import androidx.annotation.IdRes
import androidx.localbroadcastmanager.content.LocalBroadcastManager
+import androidx.navigation.findNavController
+import androidx.navigation.fragment.NavHostFragment
+import androidx.navigation.ui.NavigationUI.setupWithNavController
+import androidx.navigation.ui.setupWithNavController
import com.mina_mikhail.base_mvvm.presentation.R
import com.mina_mikhail.base_mvvm.presentation.base.BaseActivity
-import com.mina_mikhail.base_mvvm.presentation.base.extensions.setupWithNavController
import com.mina_mikhail.base_mvvm.presentation.databinding.ActivityHomeBinding
import dagger.hilt.android.AndroidEntryPoint
@@ -23,17 +26,20 @@ class HomeActivity : BaseActivity() {
private var isReceiverRegistered = false
private val openSpecificTabReceiver: BroadcastReceiver = object : BroadcastReceiver() {
- override
- fun onReceive(context: Context, intent: Intent) {
+
+ override fun onReceive(context: Context, intent: Intent) {
navigateToSpecificTab(intent.getIntExtra(TAB_ID, 0))
}
}
- override
- fun getLayoutId() = R.layout.activity_home
+ override fun getLayoutId() = R.layout.activity_home
+
+ override fun setUpViews() {
+ setUpNavController()
+ setupBottomNavigation()
+ }
- override
- fun onResume() {
+ override fun onResume() {
super.onResume()
registerOpenSpecificTabReceiver()
@@ -50,40 +56,35 @@ class HomeActivity : BaseActivity() {
}
}
- override
- fun setUpBottomNavigation() {
- setUpBottomNavigationWithGraphs()
+
+ private fun navigateToSpecificTab(@IdRes tabID: Int) {
+ binding.bottomNavigationView.selectedItemId = tabID
}
- private fun setUpBottomNavigationWithGraphs() {
- val graphIds = listOf(
- R.navigation.nav_home,
- R.navigation.nav_search,
- R.navigation.nav_account
- )
-
- val controller = binding.bottomNavigationView.setupWithNavController(
- graphIds,
- supportFragmentManager,
- R.id.fragment_host_container,
- intent
- )
-
- navController = controller
+ private fun setUpNavController() {
+ val navHostFragment = supportFragmentManager.findFragmentById(
+ R.id.fragment_host_container
+ ) as NavHostFragment
+ navController = navHostFragment.navController
}
- private fun navigateToSpecificTab(@IdRes tabID: Int) {
- binding.bottomNavigationView.selectedItemId = tabID
+ private fun setupBottomNavigation() {
+ navController.let {
+ binding.bottomNavigationView.apply {
+ inflateMenu(R.menu.menu_bottom_navigation)
+ setupWithNavController(it)
+ }
+ }
}
- override
- fun onDestroy() {
+ override fun onDestroy() {
unregisterOpenSpecificTabReceiver()
super.onDestroy()
}
private fun unregisterOpenSpecificTabReceiver() {
- LocalBroadcastManager.getInstance(this).unregisterReceiver(openSpecificTabReceiver)
+ LocalBroadcastManager.getInstance(this)
+ .unregisterReceiver(openSpecificTabReceiver)
}
}
\ No newline at end of file
diff --git a/presentation/src/main/res/layout/activity_home.xml b/presentation/src/main/res/layout/activity_home.xml
index 417d925..838b432 100644
--- a/presentation/src/main/res/layout/activity_home.xml
+++ b/presentation/src/main/res/layout/activity_home.xml
@@ -12,12 +12,13 @@
>
+ android:id="@+id/fragment_host_container"
+ android:name="androidx.navigation.fragment.NavHostFragment"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ app:defaultNavHost="true"
+ app:navGraph="@navigation/nav_main" />
+ android:orientation="vertical" >
@@ -56,7 +53,6 @@
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
- app:goneUnless="@{baseViewModel.dataLoadingEvent == DataStatus.NO_INTERNET}"
tools:ignore="UseCompoundDrawables"
>
@@ -86,7 +82,6 @@
android:layout_height="@dimen/dimen70"
android:layout_gravity="center"
app:SpinKit_Color="@color/colorPrimary"
- app:goneUnless="@{baseViewModel.dataLoadingEvent == DataStatus.LOADING}"
/>
diff --git a/presentation/src/main/res/layout/list_general.xml b/presentation/src/main/res/layout/list_general.xml
index 9ba05a1..2e8f7b3 100644
--- a/presentation/src/main/res/layout/list_general.xml
+++ b/presentation/src/main/res/layout/list_general.xml
@@ -27,7 +27,6 @@
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
- app:goneUnless="@{baseViewModel.dataLoadingEvent == DataStatus.NO_DATA}"
tools:ignore="UseCompoundDrawables"
>
@@ -55,7 +54,6 @@
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
- app:goneUnless="@{baseViewModel.dataLoadingEvent == DataStatus.NO_INTERNET}"
tools:ignore="UseCompoundDrawables"
>
@@ -85,7 +83,6 @@
android:layout_height="@dimen/dimen70"
android:layout_gravity="center"
app:SpinKit_Color="@color/colorPrimary"
- app:goneUnless="@{baseViewModel.dataLoadingEvent == DataStatus.LOADING}"
/>
diff --git a/presentation/src/main/res/navigation/nav_main.xml b/presentation/src/main/res/navigation/nav_main.xml
new file mode 100644
index 0000000..df3c0d2
--- /dev/null
+++ b/presentation/src/main/res/navigation/nav_main.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/prettyPopUp/build.gradle b/prettyPopUp/build.gradle
deleted file mode 100644
index dc23dbf..0000000
--- a/prettyPopUp/build.gradle
+++ /dev/null
@@ -1,29 +0,0 @@
-plugins {
- id 'com.android.library'
- id 'kotlin-android'
- id 'kotlin-kapt'
-}
-
-android {
- compileSdk 30
-
- defaultConfig {
- minSdk 21
- }
-
- buildTypes {
- release {
- minifyEnabled true
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-
- viewBinding {
- enabled true
- }
-}
-
-dependencies {
- implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0-alpha03"
- implementation "com.google.android.material:material:1.4.0"
-}
\ No newline at end of file
diff --git a/prettyPopUp/build.gradle.kts b/prettyPopUp/build.gradle.kts
new file mode 100644
index 0000000..0d152c6
--- /dev/null
+++ b/prettyPopUp/build.gradle.kts
@@ -0,0 +1,40 @@
+plugins {
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.android.kotlin)
+ alias(libs.plugins.kotlin.ksp)
+}
+
+android {
+ namespace = "codes.mina_mikhail.pretty_pop_up"
+ compileSdk = 34
+
+ defaultConfig {
+
+ minSdk = 21
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = true
+ proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+
+ kotlinOptions {
+ jvmTarget = JavaVersion.VERSION_17.toString()
+ }
+
+ buildFeatures {
+ viewBinding = true
+ }
+}
+
+dependencies {
+ implementation(libs.lifecycle)
+ implementation(libs.materialDesign)
+}
\ No newline at end of file
diff --git a/prettyPopUp/proguard-rules.pro b/prettyPopUp/proguard-rules.pro
index 481bb43..ff59496 100644
--- a/prettyPopUp/proguard-rules.pro
+++ b/prettyPopUp/proguard-rules.pro
@@ -1,6 +1,6 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
+# proguardFiles setting in build.gradle.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
diff --git a/prettyPopUp/src/main/AndroidManifest.xml b/prettyPopUp/src/main/AndroidManifest.xml
index 4c5cbf1..568741e 100644
--- a/prettyPopUp/src/main/AndroidManifest.xml
+++ b/prettyPopUp/src/main/AndroidManifest.xml
@@ -1,6 +1,2 @@
-
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 5b23d5c..288ba13 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,16 +1,34 @@
-rootProject.name = "Kotlin-Base-MVVM"
+pluginManagement {
+ repositories {
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ maven(url = "https://jitpack.io")
+ }
+}
-// Include all the existent modules in the project
-rootDir
- .walk()
- .maxDepth(1)
- .filter {
- it.name != rootProject.name &&
- (
- it.name != "buildSrc" && it.isDirectory && file("${it.absolutePath}/build.gradle.kts").exists() ||
- it.name != "buildSrc" && it.isDirectory && file("${it.absolutePath}/build.gradle").exists()
- )
+@Suppress("UnstableApiUsage")
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ maven(url = "https://jitpack.io")
}
- .forEach {
- include(":${it.name}")
- }
\ No newline at end of file
+}
+
+enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
+
+rootProject.name = "Kotlin-Base-MVVM"
+include(":app")
+
+// Modules
+include(":domain",":data",":presentation",":prettyPopUp",
+ ":actionChooser",":appTutorial",":imagesSlider"
+ )
\ No newline at end of file