diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 0288a6f..4982c60 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -2,10 +2,10 @@ name: Android CI/CD
on:
pull_request:
branches: [ master ]
-
- push:
+
+ push:
branches: [ master ]
-
+
workflow_dispatch:
jobs:
@@ -23,7 +23,8 @@ jobs:
GOOGLE_SERVICE: ${{ secrets.GOOGLE_SERVICE }}
run: |
echo "$GOOGLE_SERVICE" >> app/google-services.json
-
+ echo "$GOOGLE_SERVICE" >> auth/google-services.json
+
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
@@ -45,6 +46,6 @@ jobs:
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-.
-
+
- name: Build application
run: ./gradlew build --full-stacktrace
diff --git a/.github/workflows/emulator.yml b/.github/workflows/emulator.yml
index 79fc236..f5e1d11 100644
--- a/.github/workflows/emulator.yml
+++ b/.github/workflows/emulator.yml
@@ -22,6 +22,7 @@ jobs:
GOOGLE_SERVICE: ${{ secrets.GOOGLE_SERVICE }}
run: |
echo "$GOOGLE_SERVICE" >> app/google-services.json
+ echo "$GOOGLE_SERVICE" >> auth/google-services.json
- name: Set up JDK 11
uses: actions/setup-java@v3
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index d4f7c5e..fb7f4a8 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,12 +1,6 @@
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index 8fa2b66..b8c125a 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -7,11 +7,11 @@
-
+
-
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 0c3054c..3571997 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -16,10 +16,10 @@
+
-
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 71a5451..7bb2e21 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -28,6 +28,8 @@
+
+
@@ -37,11 +39,21 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -63,7 +75,7 @@
-
+
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 5565d74..150427e 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,9 +1,6 @@
plugins {
id("com.android.application")
id("kotlin-android")
- id("kotlin-kapt")
- id("kotlin-parcelize")
- id("androidx.navigation.safeargs.kotlin")
id("com.google.gms.google-services")
}
@@ -27,19 +24,6 @@ android {
"proguard-rules.pro"
)
}
- getByName("debug") {
- isTestCoverageEnabled = true
- }
- }
-
- testOptions {
- unitTests {
- isIncludeAndroidResources = true
- }
- }
-
- viewBinding {
- android.buildFeatures.viewBinding = true
}
compileOptions {
@@ -60,65 +44,5 @@ dependencies {
implementation(project(":splashscreen"))
implementation(project(":main"))
implementation(project(":auth"))
-
- implementation("org.jetbrains.kotlin:kotlin-reflect:1.6.21")
-
- /*Serialization*/
- implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2")
-
- /*Paging*/
- implementation("androidx.paging:paging-runtime-ktx:3.1.1")
-
- /*Dagger 2*/
- val daggerVersion = "2.41"
- implementation("com.google.dagger:dagger:$daggerVersion")
- implementation("com.google.dagger:dagger-android:$daggerVersion")
- implementation("com.google.dagger:dagger-android-support:$daggerVersion")
- kapt("com.google.dagger:dagger-compiler:$daggerVersion")
- kapt("com.google.dagger:dagger-android-processor:$daggerVersion")
-
- /*Firebase*/
- implementation(platform("com.google.firebase:firebase-bom:28.4.0"))
- implementation("com.google.firebase:firebase-auth:21.0.3")
- implementation("com.google.firebase:firebase-auth-ktx")
- implementation("com.google.firebase:firebase-database:20.0.4")
- implementation("com.google.android.gms:play-services-gcm:17.0.0")
- kapt("com.google.firebase:firebase-auth:21.0.3")
- implementation("com.google.firebase:firebase-storage:20.0.1")
- implementation("com.firebaseui:firebase-ui-database:8.0.1")
-
- /*Glide*/
- val glideVersion = "4.12.0"
- implementation("com.github.bumptech.glide:glide:$glideVersion")
- annotationProcessor("com.github.bumptech.glide:compiler:$glideVersion")
-
- /*Drawer Layout*/
- implementation("androidx.drawerlayout:drawerlayout:1.1.1")
-
- /*Navigation Component*/
- val navVersion = "2.4.2"
- implementation("androidx.navigation:navigation-fragment-ktx:$navVersion")
- implementation("androidx.navigation:navigation-ui-ktx:$navVersion")
- androidTestImplementation("androidx.navigation:navigation-testing:$navVersion")
-
- /*Lifecycle components*/
- val lifecycleVersion = "2.4.1"
- implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion")
- implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion")
- implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion")
-
- /*Coroutines*/
- val coroutinesVersion = "1.6.1-native-mt"
- api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
- api("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion")
-
- //noinspection DifferentStdlibGradleVersion
- implementation("org.jetbrains.kotlin:kotlin-stdlib:1.6.21")
- implementation("androidx.core:core-ktx:1.7.0")
- implementation("androidx.appcompat:appcompat:1.4.1")
- implementation("com.google.android.material:material:1.7.0-alpha01")
- implementation("androidx.constraintlayout:constraintlayout:2.1.3")
- testImplementation("junit:junit:4.13.2")
- androidTestImplementation("androidx.test.ext:junit:1.1.3")
- androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
+ implementation(project(":resources"))
}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index d99b33c..975872b 100644
--- a/app/proguard-rules.pro
+++ b/app/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.kts.kts.
+# proguardFiles setting in build.gradle.kts.kts.kts.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c3edcce..8210788 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,17 +6,16 @@
+ android:theme="@style/NewProjectTheme">
+ android:theme="@style/NewSplashTheme">
@@ -24,10 +23,11 @@
+ android:exported="false" />
+ android:exported="false"
+ android:windowSoftInputMode="stateAlwaysVisible" />
appComponent
- else -> (applicationContext as MessengerApplication).appComponent
- }
\ No newline at end of file
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
deleted file mode 100644
index 968597c..0000000
--- a/app/src/main/res/values-night/themes.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
deleted file mode 100644
index 9ebf9b4..0000000
--- a/app/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/auth/build.gradle.kts b/auth/build.gradle.kts
index 86b2a1f..1949d21 100644
--- a/auth/build.gradle.kts
+++ b/auth/build.gradle.kts
@@ -3,7 +3,6 @@ plugins {
id("kotlin-android")
id("kotlin-kapt")
id("androidx.navigation.safeargs.kotlin")
- id("com.google.gms.google-services")
}
android {
@@ -55,6 +54,7 @@ android {
dependencies {
implementation(project(":phoneedittext"))
implementation(project(":core"))
+ implementation(project(":resources"))
/*Navigation Component*/
val navVersion = "2.4.2"
@@ -71,28 +71,19 @@ dependencies {
/*Firebase*/
implementation(platform("com.google.firebase:firebase-bom:28.4.0"))
- implementation("com.google.firebase:firebase-messaging-ktx:23.0.3")
+ implementation("com.google.firebase:firebase-messaging-ktx:23.0.4")
implementation("com.google.firebase:firebase-common-ktx")
implementation("com.google.firebase:firebase-auth-ktx")
implementation("com.google.firebase:firebase-database-ktx")
implementation("com.google.firebase:firebase-storage-ktx")
implementation("com.google.firebase:firebase-analytics-ktx")
-
- /*Lifecycle components*/
- val lifecycleVersion = "2.4.1"
- implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion")
- implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion")
- implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion")
-
/*Coroutines*/
- val coroutineVersion = "1.6.1-native-mt"
- api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion")
- api("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutineVersion")
+ api("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1")
implementation("androidx.core:core-ktx:1.7.0")
implementation("androidx.appcompat:appcompat:1.4.1")
- implementation("com.google.android.material:material:1.5.0")
+ implementation("com.google.android.material:material:1.6.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.3")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.3")
diff --git a/auth/proguard-rules.pro b/auth/proguard-rules.pro
index ff59496..d99b33c 100644
--- a/auth/proguard-rules.pro
+++ b/auth/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.kts.
+# proguardFiles setting in build.gradle.kts.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
diff --git a/auth/src/main/java/st/slex/messenger/auth/data/model/AuthModel.kt b/auth/src/main/java/st/slex/messenger/auth/data/model/AuthModel.kt
deleted file mode 100644
index ed3e604..0000000
--- a/auth/src/main/java/st/slex/messenger/auth/data/model/AuthModel.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package st.slex.messenger.auth.data.model
-
-interface AuthModel {
-
- fun id(): String
- fun phone(): String
-
- data class Base(
- private val id: String,
- private val phone: String
- ) : AuthModel {
-
- override fun id(): String = id
- override fun phone(): String = phone
- }
-}
\ No newline at end of file
diff --git a/auth/src/main/java/st/slex/messenger/auth/di/AuthComponent.kt b/auth/src/main/java/st/slex/messenger/auth/di/AuthComponent.kt
index 041c2d9..fe69d0a 100644
--- a/auth/src/main/java/st/slex/messenger/auth/di/AuthComponent.kt
+++ b/auth/src/main/java/st/slex/messenger/auth/di/AuthComponent.kt
@@ -3,12 +3,10 @@ package st.slex.messenger.auth.di
import dagger.BindsInstance
import dagger.Component
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import st.slex.messenger.auth.di.scopes.AuthScope
import st.slex.messenger.auth.ui.AuthActivity
import st.slex.messenger.auth.ui.EnterCodeFragment
import st.slex.messenger.auth.ui.EnterPhoneFragment
-@AuthScope
@Component(modules = [AuthModule::class])
interface AuthComponent {
diff --git a/auth/src/main/java/st/slex/messenger/auth/di/modules/UtilsModule.kt b/auth/src/main/java/st/slex/messenger/auth/di/modules/UtilsModule.kt
index 1f902c1..ce40c1e 100644
--- a/auth/src/main/java/st/slex/messenger/auth/di/modules/UtilsModule.kt
+++ b/auth/src/main/java/st/slex/messenger/auth/di/modules/UtilsModule.kt
@@ -4,18 +4,19 @@ import dagger.Binds
import dagger.Module
import st.slex.messenger.auth.data.utils.interf.TokenUtil
import st.slex.messenger.auth.data.utils.real.TokenUtilImpl
-import st.slex.messenger.auth.ui.SendCodeEngine
-import st.slex.messenger.auth.ui.utils.LoginHelper
-import st.slex.messenger.auth.ui.utils.LoginHelperImpl
+import st.slex.messenger.auth.ui.use_case.impl.LoginUseCaseImpl
+import st.slex.messenger.auth.ui.use_case.impl.SendCodeUseCaseImpl
+import st.slex.messenger.auth.ui.use_case.interf.LoginUseCase
+import st.slex.messenger.auth.ui.use_case.interf.SendCodeUseCase
@Module
interface UtilsModule {
@Binds
- fun bindsLoginHelper(engine: LoginHelperImpl): LoginHelper
+ fun bindsLoginHelper(engine: LoginUseCaseImpl): LoginUseCase
@Binds
- fun bindsSendCodeEngine(engine: SendCodeEngine.Base): SendCodeEngine
+ fun bindsSendCodeEngine(engine: SendCodeUseCaseImpl): SendCodeUseCase
@Binds
fun bindsTokenUtilHelper(util: TokenUtilImpl): TokenUtil
diff --git a/auth/src/main/java/st/slex/messenger/auth/di/modules/ViewModelFactoryModule.kt b/auth/src/main/java/st/slex/messenger/auth/di/modules/ViewModelFactoryModule.kt
index ff4e9ca..3b89dd1 100644
--- a/auth/src/main/java/st/slex/messenger/auth/di/modules/ViewModelFactoryModule.kt
+++ b/auth/src/main/java/st/slex/messenger/auth/di/modules/ViewModelFactoryModule.kt
@@ -3,7 +3,7 @@ package st.slex.messenger.auth.di.modules
import androidx.lifecycle.ViewModelProvider
import dagger.Binds
import dagger.Module
-import st.slex.messenger.auth.ui.ViewModelFactory
+import st.slex.messenger.auth.ui.utils.ViewModelFactory
@Module
interface ViewModelFactoryModule {
diff --git a/auth/src/main/java/st/slex/messenger/auth/di/scopes/AuthScope.kt b/auth/src/main/java/st/slex/messenger/auth/di/scopes/AuthScope.kt
deleted file mode 100644
index ec94203..0000000
--- a/auth/src/main/java/st/slex/messenger/auth/di/scopes/AuthScope.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package st.slex.messenger.auth.di.scopes
-
-import javax.inject.Scope
-
-@Scope
-@Retention(value = AnnotationRetention.RUNTIME)
-annotation class AuthScope
\ No newline at end of file
diff --git a/auth/src/main/java/st/slex/messenger/auth/domain/interf/LoginDomainMapper.kt b/auth/src/main/java/st/slex/messenger/auth/domain/interf/LoginDomainMapper.kt
index 8fd31ec..8876de2 100644
--- a/auth/src/main/java/st/slex/messenger/auth/domain/interf/LoginDomainMapper.kt
+++ b/auth/src/main/java/st/slex/messenger/auth/domain/interf/LoginDomainMapper.kt
@@ -1,7 +1,7 @@
package st.slex.messenger.auth.domain.interf
import st.slex.messenger.auth.core.LoginValue
-import st.slex.messenger.auth.ui.LoginUIResult
+import st.slex.messenger.auth.ui.core.LoginUIResult
interface LoginDomainMapper {
fun map(data: LoginValue): LoginUIResult
diff --git a/auth/src/main/java/st/slex/messenger/auth/domain/real/AuthInteractorImpl.kt b/auth/src/main/java/st/slex/messenger/auth/domain/real/AuthInteractorImpl.kt
index 7005545..93b5cca 100644
--- a/auth/src/main/java/st/slex/messenger/auth/domain/real/AuthInteractorImpl.kt
+++ b/auth/src/main/java/st/slex/messenger/auth/domain/real/AuthInteractorImpl.kt
@@ -9,15 +9,15 @@ import st.slex.core.Resource
import st.slex.messenger.auth.core.LoginValue
import st.slex.messenger.auth.domain.interf.AuthInteractor
import st.slex.messenger.auth.domain.interf.AuthRepository
-import st.slex.messenger.auth.ui.SendCodeEngine
-import st.slex.messenger.auth.ui.utils.LoginHelper
+import st.slex.messenger.auth.ui.use_case.interf.LoginUseCase
+import st.slex.messenger.auth.ui.use_case.interf.SendCodeUseCase
import javax.inject.Inject
@ExperimentalCoroutinesApi
class AuthInteractorImpl @Inject constructor(
private val repository: AuthRepository,
- private val loginEngine: LoginHelper,
- private val sendCodeEngine: SendCodeEngine,
+ private val loginEngine: LoginUseCase,
+ private val sendCodeEngine: SendCodeUseCase,
) : AuthInteractor {
override suspend fun login(phone: String): Flow = flow {
diff --git a/auth/src/main/java/st/slex/messenger/auth/domain/real/LoginDomainMapperImpl.kt b/auth/src/main/java/st/slex/messenger/auth/domain/real/LoginDomainMapperImpl.kt
index 1ad8cee..595e66d 100644
--- a/auth/src/main/java/st/slex/messenger/auth/domain/real/LoginDomainMapperImpl.kt
+++ b/auth/src/main/java/st/slex/messenger/auth/domain/real/LoginDomainMapperImpl.kt
@@ -2,7 +2,7 @@ package st.slex.messenger.auth.domain.real
import st.slex.messenger.auth.core.LoginValue
import st.slex.messenger.auth.domain.interf.LoginDomainMapper
-import st.slex.messenger.auth.ui.LoginUIResult
+import st.slex.messenger.auth.ui.core.LoginUIResult
import javax.inject.Inject
class LoginDomainMapperImpl @Inject constructor() : LoginDomainMapper {
diff --git a/auth/src/main/java/st/slex/messenger/auth/ui/AuthViewModel.kt b/auth/src/main/java/st/slex/messenger/auth/ui/AuthViewModel.kt
index 919e0f4..8204ff3 100644
--- a/auth/src/main/java/st/slex/messenger/auth/ui/AuthViewModel.kt
+++ b/auth/src/main/java/st/slex/messenger/auth/ui/AuthViewModel.kt
@@ -2,10 +2,12 @@ package st.slex.messenger.auth.ui
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.*
import st.slex.messenger.auth.domain.interf.AuthInteractor
import st.slex.messenger.auth.domain.interf.LoginDomainMapper
+import st.slex.messenger.auth.ui.core.LoginUIResult
import javax.inject.Inject
@ExperimentalCoroutinesApi
@@ -14,21 +16,24 @@ class AuthViewModel @Inject constructor(
private val mapper: LoginDomainMapper
) : ViewModel() {
- suspend fun login(phone: String): StateFlow =
- interactor.login(phone)
- .flatMapLatest { flowOf(mapper.map(it)) }
- .stateIn(
- viewModelScope,
- started = SharingStarted.Lazily,
- initialValue = LoginUIResult.Loading
- )
+ suspend fun login(phone: String): StateFlow = interactor.login(phone)
+ .flatMapLatest { flowOf(mapper.map(it)) }
+ .flowOn(Dispatchers.IO)
+ .stateIn(
+ viewModelScope,
+ started = SharingStarted.Lazily,
+ initialValue = LoginUIResult.Loading
+ )
- suspend fun sendCode(id: String, code: String): Flow =
- interactor.sendCode(id, code)
- .flatMapLatest { flowOf(mapper.map(it)) }
- .stateIn(
- viewModelScope,
- started = SharingStarted.Lazily,
- initialValue = LoginUIResult.Loading
- )
+ suspend fun sendCode(
+ id: String,
+ code: String
+ ): StateFlow = interactor.sendCode(id, code)
+ .flatMapLatest { flowOf(mapper.map(it)) }
+ .flowOn(Dispatchers.IO)
+ .stateIn(
+ viewModelScope,
+ started = SharingStarted.Lazily,
+ initialValue = LoginUIResult.Loading
+ )
}
\ No newline at end of file
diff --git a/auth/src/main/java/st/slex/messenger/auth/ui/EnterCodeFragment.kt b/auth/src/main/java/st/slex/messenger/auth/ui/EnterCodeFragment.kt
index 706a22a..8226051 100644
--- a/auth/src/main/java/st/slex/messenger/auth/ui/EnterCodeFragment.kt
+++ b/auth/src/main/java/st/slex/messenger/auth/ui/EnterCodeFragment.kt
@@ -4,10 +4,12 @@ import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
+import android.util.Log
+import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.widget.EditText
+import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.Fragment
@@ -18,14 +20,15 @@ import androidx.navigation.fragment.navArgs
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.transition.MaterialContainerTransform
import dagger.Lazy
-import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import st.slex.messenger.auth.R
import st.slex.messenger.auth.databinding.FragmentEnterCodeBinding
+import st.slex.messenger.auth.ui.core.LoginUIResult
import javax.inject.Inject
-import kotlin.coroutines.suspendCoroutine
+
@ExperimentalCoroutinesApi
class EnterCodeFragment : Fragment() {
@@ -40,6 +43,9 @@ class EnterCodeFragment : Fragment() {
viewModelFactory.get()
}
+ private var sendCodeJob: Job = Job()
+ private var collectorJob: Job = Job()
+
@Inject
fun injection(viewModelFactory: Lazy) {
this.viewModelFactory = viewModelFactory
@@ -72,81 +78,80 @@ class EnterCodeFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- editTextList.first().requestFocus()
- viewLifecycleOwner.lifecycleScope.launchWhenResumed {
- foreachCodeList(editTextList) { sendCode.start() }
- }
- }
-
- private val sendCode by lazy {
- viewLifecycleOwner.lifecycleScope.launch(
- context = Dispatchers.IO,
- start = CoroutineStart.LAZY
- ) {
- viewModel.sendCode(id = args.id, code = codeFromList).collect(::collector)
+ binding.editText.requestFocus()
+ binding.editText.addTextChangedListener {
+ if (it?.length == 6) sendCode()
}
}
- private val editTextList: List by lazy {
- listOf(
- binding.codeEditText1, binding.codeEditText2, binding.codeEditText3,
- binding.codeEditText4, binding.codeEditText5, binding.codeEditText6
- )
- }
-
- private suspend inline fun foreachCodeList(
- list: List,
- crossinline startSendingCode: () -> Unit
- ) = list.indices.forEach {
- listenCode(list[it]).also { _ ->
- if (it == list.size - 1) startSendingCode()
- else list[it + 1].requestFocus()
+ private fun sendCode() {
+ sendCodeJob.cancel()
+ sendCodeJob = viewLifecycleOwner.lifecycleScope.launch(context = Dispatchers.IO) {
+ viewModel.sendCode(
+ id = args.id,
+ code = binding.editText.text.toString()
+ ).collect(::collector)
}
}
- private suspend fun listenCode(editText: EditText): Unit = suspendCoroutine { continuation ->
- editText.addTextChangedListener {
- if (it?.length == 1) continuation.resumeWith(Result.success(Unit))
+ private fun collector(resource: LoginUIResult) {
+ collectorJob.cancel()
+ collectorJob = viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
+ when (resource) {
+ is LoginUIResult.Success -> success()
+ is LoginUIResult.Failure -> failure(resource.exception)
+ is LoginUIResult.Loading -> showProgress()
+ }
}
}
- private val codeFromList: String
- get() = editTextList.joinToString { it.text.toString() }.replace(", ", "")
-
- private fun collector(
- resource: LoginUIResult
- ) = viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
- when (resource) {
- is LoginUIResult.Success -> success()
- is LoginUIResult.Failure -> stopProgress()
- is LoginUIResult.Loading -> showProgress()
- }
+ private fun failure(exception: Exception) {
+ binding.editText.setText("")
+ stopProgress()
+ showError(exception)
}
private fun success() {
stopProgress()
val intent = Intent()
intent.setClassName(requireContext(), MAIN_ACTIVITY_PATH)
+ Snackbar.make(binding.root, "SUCCESS", Snackbar.LENGTH_LONG).show()
startActivity(intent)
requireActivity().finish()
- Snackbar.make(binding.root, "SUCCESS", Snackbar.LENGTH_LONG).show()
- }
-
- private fun showProgress() {
- binding.fragmentCodeProgressIndicator.visibility = View.VISIBLE
}
private fun stopProgress() {
binding.fragmentCodeProgressIndicator.visibility = View.GONE
}
+ private fun showProgress() {
+ binding.fragmentCodeProgressIndicator.visibility = View.VISIBLE
+ }
+
override fun onDestroyView() {
super.onDestroyView()
+ sendCodeJob.cancel()
+ collectorJob.cancel()
_binding = null
}
+ private fun showError(throwable: Throwable) {
+ if (isVisible) {
+ Snackbar.make(
+ binding.root,
+ throwable.message.toString(),
+ Snackbar.LENGTH_SHORT
+ ).apply {
+ setAction("OK") {}
+ (view.layoutParams as FrameLayout.LayoutParams).gravity = Gravity.TOP
+ }.show()
+ }
+ Log.e(TAG, throwable.stackTraceToString())
+ }
+
companion object {
private const val MAIN_ACTIVITY_PATH = "st.slex.messenger.main.ui.MainActivity"
+ private const val TAG = "EnterCodeFragment"
}
}
diff --git a/auth/src/main/java/st/slex/messenger/auth/ui/EnterPhoneFragment.kt b/auth/src/main/java/st/slex/messenger/auth/ui/EnterPhoneFragment.kt
index 5b23064..2dc6e95 100644
--- a/auth/src/main/java/st/slex/messenger/auth/ui/EnterPhoneFragment.kt
+++ b/auth/src/main/java/st/slex/messenger/auth/ui/EnterPhoneFragment.kt
@@ -1,13 +1,14 @@
package st.slex.messenger.auth.ui
+import android.app.Activity
import android.content.Context
-import android.content.Context.INPUT_METHOD_SERVICE
import android.content.Intent
+import android.graphics.Color
import android.os.Bundle
+import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.Fragment
@@ -16,13 +17,16 @@ import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
-import com.google.android.material.textfield.TextInputEditText
-import dagger.Lazy
+import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import st.slex.messenger.auth.databinding.FragmentEnterPhoneBinding
+import st.slex.messenger.auth.ui.core.LoginUIResult
+import st.slex.resources.KeyboardUtil
+import st.slex.resources.KeyboardUtilImpl
+import java.lang.ref.WeakReference
import java.util.*
import javax.inject.Inject
@@ -32,12 +36,17 @@ class EnterPhoneFragment : Fragment() {
private var _binding: FragmentEnterPhoneBinding? = null
private val binding get() = checkNotNull(_binding)
- private lateinit var viewModelFactory: Lazy
- private val viewModel: AuthViewModel by viewModels { viewModelFactory.get() }
+ private lateinit var viewModelFactory: ViewModelProvider.Factory
+ private val viewModel: AuthViewModel by viewModels { viewModelFactory }
private var phoneClickJob: Job = Job()
+ private var collectorJob: Job = Job()
+
+ private var _weakReference: WeakReference? = null
+ private val weakReference: WeakReference
+ get() = checkNotNull(_weakReference)
@Inject
- fun injection(viewModelFactory: Lazy) {
+ fun injection(viewModelFactory: ViewModelProvider.Factory) {
this.viewModelFactory = viewModelFactory
}
@@ -52,58 +61,63 @@ class EnterPhoneFragment : Fragment() {
savedInstanceState: Bundle?
): View {
_binding = FragmentEnterPhoneBinding.inflate(inflater, container, false)
- (activity as AppCompatActivity).supportActionBar?.title = "Phone Number"
+ (activity as AppCompatActivity).supportActionBar?.title = FRAGMENT_TITLE
+ _weakReference = WeakReference(requireActivity())
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- showKeyboard(binding.phoneEditText)
+ val keyboardUtil: KeyboardUtil = KeyboardUtilImpl(weakReference)
+ binding.phoneEditText.requestFocus()
binding.phoneEditText.setRegionCode(Locale.getDefault().country)
binding.phoneEditText.addTextChangedListener {
- binding.fragmentPhoneFab.isEnabled =
- binding.phoneEditText.isTextValidInternationalPhoneNumber()
+ if (binding.phoneEditText.isTextValidInternationalPhoneNumber()) {
+ binding.fragmentPhoneFab.isEnabled = true
+ keyboardUtil.hideKeyboard()
+ } else {
+ binding.fragmentPhoneFab.isEnabled = false
+ }
}
binding.fragmentPhoneFab.setOnClickListener(phoneClickListener)
}
private val phoneClickListener = View.OnClickListener {
phoneClickJob.cancel()
- val phone = binding.phoneEditText.text.toString()
phoneClickJob = requireActivity().lifecycleScope.launch(Dispatchers.IO) {
+ val phone = binding.phoneEditText.text.toString()
viewModel.login(phone).collect(::collector)
}
}
- private fun showKeyboard(textInputEditText: TextInputEditText) {
- textInputEditText.requestFocus()
- val inputMethodManager =
- requireActivity().getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
- inputMethodManager.showSoftInput(textInputEditText, InputMethodManager.SHOW_IMPLICIT)
- }
-
private fun collector(resource: LoginUIResult) {
- viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
+ collectorJob.cancel()
+ collectorJob = viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
when (resource) {
is LoginUIResult.Success.LogIn -> resultLogIn()
- is LoginUIResult.Success.SendCode -> resource.resultSendCode()
- is LoginUIResult.Failure -> stopProgress()
+ is LoginUIResult.Success.SendCode -> resultSendCode(resource.id)
+ is LoginUIResult.Failure -> failureResult(resource.exception)
is LoginUIResult.Loading -> showProgress()
}
}
}
+ private fun failureResult(exception: Exception) {
+ stopProgress()
+ exception.cause?.let(::showError)
+ }
+
private fun resultLogIn() {
val intent = Intent()
intent.setClassName(requireContext(), MAIN_ACTIVITY_PATH)
startActivity(intent)
}
- private fun LoginUIResult.Success.SendCode.resultSendCode() {
- binding.fragmentCodeProgressIndicator.visibility = View.GONE
- val direction = EnterPhoneFragmentDirections.actionNavAuthPhoneToNavAuthCode(id)
- val extras =
- FragmentNavigatorExtras(binding.fragmentPhoneFab to binding.fragmentPhoneFab.transitionName)
+ private fun resultSendCode(id: String) {
+ stopProgress()
+ val direction = EnterPhoneFragmentDirections.actionNavCode(id)
+ val sharedElements = binding.fragmentPhoneFab to binding.fragmentPhoneFab.transitionName
+ val extras = FragmentNavigatorExtras(sharedElements)
findNavController().navigate(direction, extras)
}
@@ -118,14 +132,33 @@ class EnterPhoneFragment : Fragment() {
override fun onDestroyView() {
super.onDestroyView()
_binding = null
+ weakReference.clear()
+ _weakReference = null
}
override fun onDestroy() {
super.onDestroy()
phoneClickJob.cancel()
+ collectorJob.cancel()
+ }
+
+ private fun showError(throwable: Throwable) {
+ if (isVisible) {
+ Snackbar.make(
+ requireView(),
+ throwable.message.toString(),
+ Snackbar.LENGTH_SHORT
+ ).apply {
+ setBackgroundTint(Color.CYAN)
+ setAction("OK") {}
+ }.show()
+ }
+ Log.e(TAG, throwable.stackTraceToString())
}
companion object {
private const val MAIN_ACTIVITY_PATH = "st.slex.messenger.main.ui.MainActivity"
+ private const val FRAGMENT_TITLE = "Phone number"
+ private const val TAG = "EnterPhoneFragment"
}
}
diff --git a/auth/src/main/java/st/slex/messenger/auth/ui/SendCodeEngine.kt b/auth/src/main/java/st/slex/messenger/auth/ui/SendCodeEngine.kt
deleted file mode 100644
index ba606d3..0000000
--- a/auth/src/main/java/st/slex/messenger/auth/ui/SendCodeEngine.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package st.slex.messenger.auth.ui
-
-import com.google.android.gms.tasks.OnCompleteListener
-import com.google.firebase.auth.AuthResult
-import com.google.firebase.auth.PhoneAuthProvider
-import com.google.firebase.auth.ktx.auth
-import com.google.firebase.ktx.Firebase
-import st.slex.messenger.auth.core.LoginValue
-import javax.inject.Inject
-import kotlin.coroutines.suspendCoroutine
-
-interface SendCodeEngine {
-
- suspend fun sendCode(id: String, code: String): LoginValue
-
- class Base @Inject constructor() : SendCodeEngine {
-
- override suspend fun sendCode(id: String, code: String): LoginValue =
- suspendCoroutine { continuation ->
- val credential = PhoneAuthProvider.getCredential(id, code)
- val task = Firebase.auth.signInWithCredential(credential)
- val listener = listener { continuation.resumeWith(Result.success(it)) }
- task.addOnCompleteListener(listener)
- }
-
- private inline fun listener(
- crossinline function: (LoginValue) -> Unit
- ) = OnCompleteListener {
- val authResult = if (it.isSuccessful) LoginValue.Success.LogIn
- else LoginValue.Failure(it.exception!!)
- function(authResult)
- }
- }
-}
\ No newline at end of file
diff --git a/auth/src/main/java/st/slex/messenger/auth/ui/LoginUIResult.kt b/auth/src/main/java/st/slex/messenger/auth/ui/core/LoginUIResult.kt
similarity index 87%
rename from auth/src/main/java/st/slex/messenger/auth/ui/LoginUIResult.kt
rename to auth/src/main/java/st/slex/messenger/auth/ui/core/LoginUIResult.kt
index 8773bfb..22dd5b9 100644
--- a/auth/src/main/java/st/slex/messenger/auth/ui/LoginUIResult.kt
+++ b/auth/src/main/java/st/slex/messenger/auth/ui/core/LoginUIResult.kt
@@ -1,4 +1,4 @@
-package st.slex.messenger.auth.ui
+package st.slex.messenger.auth.ui.core
sealed class LoginUIResult {
diff --git a/auth/src/main/java/st/slex/messenger/auth/ui/utils/LoginHelperImpl.kt b/auth/src/main/java/st/slex/messenger/auth/ui/use_case/impl/LoginUseCaseImpl.kt
similarity index 86%
rename from auth/src/main/java/st/slex/messenger/auth/ui/utils/LoginHelperImpl.kt
rename to auth/src/main/java/st/slex/messenger/auth/ui/use_case/impl/LoginUseCaseImpl.kt
index 7432218..6fd43f2 100644
--- a/auth/src/main/java/st/slex/messenger/auth/ui/utils/LoginHelperImpl.kt
+++ b/auth/src/main/java/st/slex/messenger/auth/ui/use_case/impl/LoginUseCaseImpl.kt
@@ -1,4 +1,4 @@
-package st.slex.messenger.auth.ui.utils
+package st.slex.messenger.auth.ui.use_case.impl
import com.google.firebase.auth.PhoneAuthOptions
import com.google.firebase.auth.PhoneAuthProvider
@@ -6,13 +6,14 @@ import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
import st.slex.messenger.auth.core.LoginValue
import st.slex.messenger.auth.ui.AuthActivity
+import st.slex.messenger.auth.ui.use_case.interf.LoginUseCase
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import kotlin.coroutines.suspendCoroutine
-class LoginHelperImpl @Inject constructor(
+class LoginUseCaseImpl @Inject constructor(
private val activity: AuthActivity
-) : LoginHelper {
+) : LoginUseCase {
override suspend fun login(phone: String): LoginValue =
suspendCoroutine { continuation ->
diff --git a/auth/src/main/java/st/slex/messenger/auth/ui/utils/PhoneAuthCallback.kt b/auth/src/main/java/st/slex/messenger/auth/ui/use_case/impl/PhoneAuthCallback.kt
similarity index 95%
rename from auth/src/main/java/st/slex/messenger/auth/ui/utils/PhoneAuthCallback.kt
rename to auth/src/main/java/st/slex/messenger/auth/ui/use_case/impl/PhoneAuthCallback.kt
index 5e8a829..6e8d21c 100644
--- a/auth/src/main/java/st/slex/messenger/auth/ui/utils/PhoneAuthCallback.kt
+++ b/auth/src/main/java/st/slex/messenger/auth/ui/use_case/impl/PhoneAuthCallback.kt
@@ -1,4 +1,4 @@
-package st.slex.messenger.auth.ui.utils
+package st.slex.messenger.auth.ui.use_case.impl
import com.google.firebase.FirebaseException
import com.google.firebase.auth.PhoneAuthCredential
diff --git a/auth/src/main/java/st/slex/messenger/auth/ui/use_case/impl/SendCodeUseCaseImpl.kt b/auth/src/main/java/st/slex/messenger/auth/ui/use_case/impl/SendCodeUseCaseImpl.kt
new file mode 100644
index 0000000..66c6e94
--- /dev/null
+++ b/auth/src/main/java/st/slex/messenger/auth/ui/use_case/impl/SendCodeUseCaseImpl.kt
@@ -0,0 +1,30 @@
+package st.slex.messenger.auth.ui.use_case.impl
+
+import com.google.android.gms.tasks.OnCompleteListener
+import com.google.firebase.auth.AuthResult
+import com.google.firebase.auth.PhoneAuthProvider
+import com.google.firebase.auth.ktx.auth
+import com.google.firebase.ktx.Firebase
+import st.slex.messenger.auth.core.LoginValue
+import st.slex.messenger.auth.ui.use_case.interf.SendCodeUseCase
+import javax.inject.Inject
+import kotlin.coroutines.suspendCoroutine
+
+class SendCodeUseCaseImpl @Inject constructor() : SendCodeUseCase {
+
+ override suspend fun sendCode(id: String, code: String): LoginValue =
+ suspendCoroutine { continuation ->
+ val credential = PhoneAuthProvider.getCredential(id, code)
+ val task = Firebase.auth.signInWithCredential(credential)
+ val listener = listener { continuation.resumeWith(Result.success(it)) }
+ task.addOnCompleteListener(listener)
+ }
+
+ private inline fun listener(
+ crossinline function: (LoginValue) -> Unit
+ ) = OnCompleteListener {
+ val authResult = if (it.isSuccessful) LoginValue.Success.LogIn
+ else LoginValue.Failure(it.exception!!)
+ function(authResult)
+ }
+}
\ No newline at end of file
diff --git a/auth/src/main/java/st/slex/messenger/auth/ui/utils/LoginHelper.kt b/auth/src/main/java/st/slex/messenger/auth/ui/use_case/interf/LoginUseCase.kt
similarity index 56%
rename from auth/src/main/java/st/slex/messenger/auth/ui/utils/LoginHelper.kt
rename to auth/src/main/java/st/slex/messenger/auth/ui/use_case/interf/LoginUseCase.kt
index 4a06c7f..03e0034 100644
--- a/auth/src/main/java/st/slex/messenger/auth/ui/utils/LoginHelper.kt
+++ b/auth/src/main/java/st/slex/messenger/auth/ui/use_case/interf/LoginUseCase.kt
@@ -1,7 +1,7 @@
-package st.slex.messenger.auth.ui.utils
+package st.slex.messenger.auth.ui.use_case.interf
import st.slex.messenger.auth.core.LoginValue
-interface LoginHelper {
+interface LoginUseCase {
suspend fun login(phone: String): LoginValue
}
\ No newline at end of file
diff --git a/auth/src/main/java/st/slex/messenger/auth/ui/use_case/interf/SendCodeUseCase.kt b/auth/src/main/java/st/slex/messenger/auth/ui/use_case/interf/SendCodeUseCase.kt
new file mode 100644
index 0000000..9bb1a07
--- /dev/null
+++ b/auth/src/main/java/st/slex/messenger/auth/ui/use_case/interf/SendCodeUseCase.kt
@@ -0,0 +1,7 @@
+package st.slex.messenger.auth.ui.use_case.interf
+
+import st.slex.messenger.auth.core.LoginValue
+
+interface SendCodeUseCase {
+ suspend fun sendCode(id: String, code: String): LoginValue
+}
\ No newline at end of file
diff --git a/auth/src/main/java/st/slex/messenger/auth/ui/ViewModelFactory.kt b/auth/src/main/java/st/slex/messenger/auth/ui/utils/ViewModelFactory.kt
similarity index 95%
rename from auth/src/main/java/st/slex/messenger/auth/ui/ViewModelFactory.kt
rename to auth/src/main/java/st/slex/messenger/auth/ui/utils/ViewModelFactory.kt
index 3380316..1b6cb5b 100644
--- a/auth/src/main/java/st/slex/messenger/auth/ui/ViewModelFactory.kt
+++ b/auth/src/main/java/st/slex/messenger/auth/ui/utils/ViewModelFactory.kt
@@ -1,4 +1,4 @@
-package st.slex.messenger.auth.ui
+package st.slex.messenger.auth.ui.utils
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
diff --git a/auth/src/main/res/layout/fragment_enter_code.xml b/auth/src/main/res/layout/fragment_enter_code.xml
index f5b1656..b5ad288 100644
--- a/auth/src/main/res/layout/fragment_enter_code.xml
+++ b/auth/src/main/res/layout/fragment_enter_code.xml
@@ -5,70 +5,28 @@
android:layout_height="match_parent"
tools:context=".ui.EnterCodeFragment">
-
+ android:hint="@string/code">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:inputType="number"
+ android:lines="1"
+ android:maxLength="6"
+ android:textSize="40sp" />
+
-
diff --git a/auth/src/main/res/layout/fragment_enter_phone.xml b/auth/src/main/res/layout/fragment_enter_phone.xml
index e815473..d8e09af 100644
--- a/auth/src/main/res/layout/fragment_enter_phone.xml
+++ b/auth/src/main/res/layout/fragment_enter_phone.xml
@@ -8,7 +8,7 @@
+ app:startDestination="@id/nav_phone">
+ android:id="@+id/action_nav_code"
+ app:destination="@id/nav_code" />
+
+
+
+
\ No newline at end of file
diff --git a/auth/src/main/res/values-night/themes.xml b/auth/src/main/res/values-night/themes.xml
deleted file mode 100644
index db2d048..0000000
--- a/auth/src/main/res/values-night/themes.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/auth/src/main/res/values/styles.xml b/auth/src/main/res/values/styles.xml
new file mode 100644
index 0000000..821da98
--- /dev/null
+++ b/auth/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/auth/src/main/res/values/themes.xml b/auth/src/main/res/values/themes.xml
deleted file mode 100644
index 1ba5e45..0000000
--- a/auth/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
deleted file mode 100644
index 5e7beb0..0000000
--- a/build.gradle
+++ /dev/null
@@ -1,28 +0,0 @@
-buildscript {
- ext {
- kotlin_version = "1.6.21"
- nav_version = '2.4.2'
- }
- repositories {
- google()
- mavenCentral()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:7.1.3'
- classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21'
- classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
- classpath 'com.google.gms:google-services:4.3.10'
- }
-}
-
-allprojects {
- repositories {
- google()
- mavenCentral()
- maven { url 'https://jitpack.io' }
- }
-}
-
-task clean(type: Delete) {
- delete rootProject.buildDir
-}
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 0000000..751e8de
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,28 @@
+import java.net.URI
+
+buildscript {
+ repositories {
+ google()
+ mavenCentral()
+ }
+ dependencies {
+ classpath("com.android.tools.build:gradle:7.1.3")
+ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21")
+ classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.4.2")
+ classpath("com.google.gms:google-services:4.3.10")
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ maven {
+ url = URI("https://jitpack.io")
+ }
+ }
+}
+
+tasks.register(name = "type", type = Delete::class) {
+ delete(rootProject.buildDir)
+}
\ No newline at end of file
diff --git a/core/build.gradle.kts b/core/build.gradle.kts
index 0d31ad5..d182641 100644
--- a/core/build.gradle.kts
+++ b/core/build.gradle.kts
@@ -4,6 +4,6 @@ plugins {
}
java {
- sourceCompatibility = JavaVersion.VERSION_1_7
- targetCompatibility = JavaVersion.VERSION_1_7
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
}
\ No newline at end of file
diff --git a/main/build.gradle b/main/build.gradle
deleted file mode 100644
index f67718b..0000000
--- a/main/build.gradle
+++ /dev/null
@@ -1,102 +0,0 @@
-plugins {
- id 'com.android.library'
- id 'kotlin-android'
- id 'kotlin-kapt'
- id 'kotlin-parcelize'
- id 'androidx.navigation.safeargs.kotlin'
- id 'com.google.gms.google-services'
-}
-
-android {
- compileSdk 31
-
- defaultConfig {
- minSdk 23
- targetSdk 31
-
- testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
- consumerProguardFiles "consumer-rules.pro"
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
- }
- }
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
- kotlinOptions {
- jvmTarget = '1.8'
- }
- buildFeatures {
- viewBinding true
- }
-}
-
-dependencies {
- implementation(project(":core"))
- implementation "org.jetbrains.kotlin:kotlin-reflect:1.5.31"
-
- /*Work Manager*/
- implementation "androidx.work:work-runtime-ktx:2.7.0"
-
- /*Serialization*/
- implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.0-RC")
-
- /*Paging*/
- implementation("androidx.paging:paging-runtime-ktx:3.0.1")
-
- /*Dagger 2*/
- implementation("com.google.dagger:dagger:2.39.1")
- implementation("androidx.legacy:legacy-support-v4:1.0.0")
- implementation("com.google.dagger:dagger-android:2.37")
- implementation("com.google.dagger:dagger-android-support:2.37")
- kapt("com.google.dagger:dagger-compiler:2.37")
- kapt("com.google.dagger:dagger-android-processor:2.37")
-
- /*Firebase*/
- implementation platform('com.google.firebase:firebase-bom:28.4.0')
- implementation('com.google.firebase:firebase-auth')
- implementation('com.google.firebase:firebase-auth-ktx')
- implementation('com.google.firebase:firebase-database')
- implementation 'com.google.firebase:firebase-messaging-ktx'
- implementation 'com.google.firebase:firebase-analytics-ktx'
- implementation("com.google.firebase:firebase-storage")
- implementation("com.firebaseui:firebase-ui-database:8.0.0")
- implementation("com.google.android.gms:play-services-gcm:17.0.0")
- kapt('com.google.firebase:firebase-auth:21.0.1')
-
- /*Glide*/
- implementation 'com.github.bumptech.glide:glide:4.11.0'
- implementation 'androidx.legacy:legacy-support-v4:1.0.0'
- annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
-
- /*Drawer Layout*/
- implementation "androidx.drawerlayout:drawerlayout:1.1.1"
-
- /*Navigation Component*/
- implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
- implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
-
- /*Testing Navigation*/
- androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"
-
- /*Lifecycle components*/
- implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"
- implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
- implementation "androidx.lifecycle:lifecycle-common-java8:2.3.1"
-
- /*Coroutines*/
- api 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
- api 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2-native-mt'
-
- implementation 'androidx.core:core-ktx:1.6.0'
- implementation 'androidx.appcompat:appcompat:1.3.1'
- implementation 'com.google.android.material:material:1.5.0-alpha04'
- testImplementation 'junit:junit:4.+'
- androidTestImplementation 'androidx.test.ext:junit:1.1.3'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
-}
\ No newline at end of file
diff --git a/main/build.gradle.kts b/main/build.gradle.kts
new file mode 100644
index 0000000..76d3ce2
--- /dev/null
+++ b/main/build.gradle.kts
@@ -0,0 +1,112 @@
+plugins {
+ id("com.android.library")
+ id("kotlin-android")
+ id("kotlin-kapt")
+ id("kotlin-parcelize")
+ id("androidx.navigation.safeargs.kotlin")
+}
+
+android {
+ compileSdk = 32
+
+ defaultConfig {
+ minSdk = 23
+ targetSdk = 32
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ getByName("release") {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ getByName("debug") {
+ isTestCoverageEnabled = true
+ }
+ }
+
+ testOptions {
+ unitTests {
+ isIncludeAndroidResources = true
+ }
+ }
+
+ viewBinding {
+ android.buildFeatures.viewBinding = true
+ }
+
+ compileOptions {
+ sourceCompatibility(JavaVersion.VERSION_11)
+ targetCompatibility(JavaVersion.VERSION_11)
+ }
+
+ sourceSets {
+ getByName("androidTest").assets.srcDir("$projectDir/schemas")
+ }
+
+ kotlinOptions {
+ jvmTarget = "11"
+ }
+}
+
+dependencies {
+ implementation(project(":core"))
+ implementation(project(":resources"))
+
+ implementation("org.jetbrains.kotlin:kotlin-reflect:1.6.21")
+
+ /*Work Manager*/
+ implementation("androidx.work:work-runtime-ktx:2.7.1")
+
+ /*Serialization*/
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2")
+
+ /*Paging*/
+ implementation("androidx.paging:paging-runtime-ktx:3.1.1")
+
+ /*Dagger 2*/
+ implementation("com.google.dagger:dagger:2.41")
+ implementation("com.google.dagger:dagger-android:2.41")
+ implementation("com.google.dagger:dagger-android-support:2.41")
+ kapt("com.google.dagger:dagger-compiler:2.41")
+ kapt("com.google.dagger:dagger-android-processor:2.41")
+
+ /*Firebase*/
+ implementation(platform("com.google.firebase:firebase-bom:28.4.0"))
+ implementation("com.google.firebase:firebase-auth")
+ implementation("com.google.firebase:firebase-auth-ktx")
+ implementation("com.google.firebase:firebase-database")
+ implementation("com.google.firebase:firebase-messaging-ktx")
+ implementation("com.google.firebase:firebase-analytics-ktx")
+ implementation("com.google.firebase:firebase-storage")
+ implementation("com.firebaseui:firebase-ui-database:8.0.1")
+ implementation("com.google.android.gms:play-services-gcm:17.0.0")
+ kapt("com.google.firebase:firebase-auth:21.0.3")
+
+ /*Glide*/
+ implementation("com.github.bumptech.glide:glide:4.13.1")
+ annotationProcessor("com.github.bumptech.glide:compiler:4.12.0")
+
+ /*Drawer Layout*/
+ implementation("androidx.drawerlayout:drawerlayout:1.1.1")
+
+ /*Navigation Component*/
+ val navVersion = "2.4.2"
+ implementation("androidx.navigation:navigation-fragment-ktx:$navVersion")
+ implementation("androidx.navigation:navigation-ui-ktx:$navVersion")
+ androidTestImplementation("androidx.navigation:navigation-testing:$navVersion")
+
+ /*Coroutines*/
+ api("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1-native-mt")
+
+ implementation("androidx.core:core-ktx:1.7.0")
+ implementation("androidx.appcompat:appcompat:1.4.1")
+ implementation("com.google.android.material:material:1.7.0-alpha01")
+ testImplementation("junit:junit:4.13.2")
+ androidTestImplementation("androidx.test.ext:junit:1.1.3")
+ androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
+}
\ No newline at end of file
diff --git a/main/proguard-rules.pro b/main/proguard-rules.pro
index 481bb43..ff59496 100644
--- a/main/proguard-rules.pro
+++ b/main/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/main/src/main/AndroidManifest.xml b/main/src/main/AndroidManifest.xml
index a051063..097c4d7 100644
--- a/main/src/main/AndroidManifest.xml
+++ b/main/src/main/AndroidManifest.xml
@@ -1,4 +1,2 @@
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/main/src/main/java/st/slex/messenger/main/ui/chats/ChatsFragment.kt b/main/src/main/java/st/slex/messenger/main/ui/chats/ChatsFragment.kt
index 9fad573..d03096c 100644
--- a/main/src/main/java/st/slex/messenger/main/ui/chats/ChatsFragment.kt
+++ b/main/src/main/java/st/slex/messenger/main/ui/chats/ChatsFragment.kt
@@ -24,7 +24,6 @@ import st.slex.messenger.main.databinding.FragmentChatsBinding
import st.slex.messenger.main.databinding.NavigationDrawerHeaderBinding
import st.slex.messenger.main.ui.MainActivity
import st.slex.messenger.main.ui.core.BaseFragment
-import st.slex.messenger.main.ui.core.UIExtensions.changeVisibility
import st.slex.messenger.main.ui.user_profile.UserUI
import javax.inject.Inject
@@ -121,7 +120,7 @@ class ChatsFragment : BaseFragment() {
}
}
is Resource.Failure<*> -> result.failureResult(view)
- is Resource.Loading -> view.loadingResult()
+ is Resource.Loading -> showLoading()
}
}
@@ -136,13 +135,13 @@ class ChatsFragment : BaseFragment() {
@JvmName("collectorUserUI")
private suspend fun Resource.Success.successResult(view: View) {
- view.changeVisibility()
+ hideLoading()
drawResult(data)
}
@JvmName("collectorChatsUI")
private suspend fun Resource.Success>>.successResult(view: View) {
- view.changeVisibility()
+ hideLoading()
drawResult(data)
}
@@ -160,11 +159,17 @@ class ChatsFragment : BaseFragment() {
}
private suspend fun Resource.Failure.failureResult(view: View) {
- view.changeVisibility()
+ hideLoading()
Log.e(TAG, exception.message, exception.cause)
}
- private suspend fun View.loadingResult() = changeVisibility()
+ private fun showLoading() {
+ binding.SHOWPROGRESS.show()
+ }
+
+ private fun hideLoading() {
+ binding.SHOWPROGRESS.hide()
+ }
override fun onDestroyView() {
super.onDestroyView()
diff --git a/main/src/main/java/st/slex/messenger/main/ui/core/ViewModelFactory.kt b/main/src/main/java/st/slex/messenger/main/ui/core/ViewModelFactory.kt
index e5e01ec..68144ec 100644
--- a/main/src/main/java/st/slex/messenger/main/ui/core/ViewModelFactory.kt
+++ b/main/src/main/java/st/slex/messenger/main/ui/core/ViewModelFactory.kt
@@ -9,18 +9,17 @@ class ViewModelFactory @Inject constructor(
private val viewModelMap: Map, @JvmSuppressWildcards Provider>
) : ViewModelProvider.Factory {
- override fun create(modelClass: Class): T {
- var viewModel = viewModelMap[modelClass]
- if (viewModel == null) {
- for (entry in viewModelMap) {
- if (modelClass.isAssignableFrom(entry.key)) {
- viewModel = entry.value
- break
- }
- }
- }
- if (viewModel == null) throw IllegalArgumentException("Unknown model class $modelClass")
- @Suppress("UNCHECKED_CAST")
- return viewModel.get() as T
- }
+ override fun create(modelClass: Class): T = viewModelMap[modelClass]
+ ?.let(::viewModelMapper)
+ ?: modelClass.filterViewModelMap?.let(::viewModelMapper)
+ ?: throw IllegalArgumentException("Unknown model class $modelClass")
+
+ @Suppress("UNCHECKED_CAST")
+ private fun viewModelMapper(provider: Provider): T =
+ provider.get() as T
+
+ private val Class.filterViewModelMap: Provider?
+ get() = viewModelMap.filter {
+ isAssignableFrom(it.key)
+ }.firstNotNullOfOrNull { it.value }
}
\ No newline at end of file
diff --git a/main/src/main/java/st/slex/messenger/main/ui/single_chat/MessageUI.kt b/main/src/main/java/st/slex/messenger/main/ui/single_chat/MessageUI.kt
index 8393732..e6d87ff 100644
--- a/main/src/main/java/st/slex/messenger/main/ui/single_chat/MessageUI.kt
+++ b/main/src/main/java/st/slex/messenger/main/ui/single_chat/MessageUI.kt
@@ -1,6 +1,7 @@
package st.slex.messenger.main.ui.single_chat
import android.view.View
+import android.view.ViewGroup
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import st.slex.messenger.main.utilites.funs.convertToTime
@@ -8,8 +9,8 @@ import st.slex.messenger.main.utilites.funs.convertToTime
interface MessageUI {
fun bindMessage(
- hideLayout: ConstraintLayout,
- showLayout: ConstraintLayout,
+ hideLayout: ViewGroup,
+ showLayout: ViewGroup,
messageTextView: TextView,
timeStampTextView: TextView
)
@@ -25,8 +26,8 @@ interface MessageUI {
override fun getId(): String = from
override fun bindMessage(
- hideLayout: ConstraintLayout,
- showLayout: ConstraintLayout,
+ hideLayout: ViewGroup,
+ showLayout: ViewGroup,
messageTextView: TextView,
timeStampTextView: TextView
) {
diff --git a/main/src/main/java/st/slex/messenger/main/ui/single_chat/SingleChatFragment.kt b/main/src/main/java/st/slex/messenger/main/ui/single_chat/SingleChatFragment.kt
index 195fce3..2374df7 100644
--- a/main/src/main/java/st/slex/messenger/main/ui/single_chat/SingleChatFragment.kt
+++ b/main/src/main/java/st/slex/messenger/main/ui/single_chat/SingleChatFragment.kt
@@ -5,6 +5,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.view.inputmethod.InputMethodManager
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
@@ -88,11 +89,11 @@ class SingleChatFragment : BaseFragment() {
private val sendClicker: View.OnClickListener
get() = View.OnClickListener {
- val message = binding.singleChatRecyclerTextInput.editText?.text.toString()
+ val message = binding.editText.text.toString()
if (message.isEmpty()) {
val snackBar =
Snackbar.make(binding.root, "Empty message", Snackbar.LENGTH_SHORT)
- snackBar.anchorView = binding.singleChatRecyclerTextInput
+ snackBar.anchorView = binding.editText
snackBar.setAction("Ok") {}
snackBar.show()
} else {
@@ -107,7 +108,14 @@ class SingleChatFragment : BaseFragment() {
private suspend fun collect(result: Resource) = withContext(Dispatchers.Main) {
if (result is Resource.Success) {
binding.singleChatRecycler.scrollToPosition(adapter.itemCount)
- binding.singleChatRecyclerTextInput.editText?.setText("")
+ val hidingView = requireActivity().currentFocus
+ val inputMethodManager =
+ requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ inputMethodManager.hideSoftInputFromWindow(
+ hidingView!!.windowToken,
+ InputMethodManager.RESULT_UNCHANGED_SHOWN
+ )
+ binding.editText.setText("")
}
}
diff --git a/main/src/main/java/st/slex/messenger/main/utilites/base/GlideBase.kt b/main/src/main/java/st/slex/messenger/main/utilites/base/GlideBase.kt
index 311db4f..565c36a 100644
--- a/main/src/main/java/st/slex/messenger/main/utilites/base/GlideBase.kt
+++ b/main/src/main/java/st/slex/messenger/main/utilites/base/GlideBase.kt
@@ -23,11 +23,12 @@ value class GlideBase(
needCircleCrop: Boolean = false,
needOriginal: Boolean = false
) {
- val urlSet = if (url == "null" || url == "") {
+ val urlSet = if (url == "null" || url.isEmpty()) {
R.drawable.ic_default_photo
} else url
val glide = Glide.with(imageView)
.load(urlSet)
+ .placeholder(R.drawable.ic_default_photo)
.listener(primaryRequestListener)
if (needCrop) glide.centerCrop()
if (needCircleCrop) glide.circleCrop()
diff --git a/main/src/main/java/st/slex/messenger/main/utilites/base/SetImageWithGlide.kt b/main/src/main/java/st/slex/messenger/main/utilites/base/SetImageWithGlide.kt
index a873590..33d8fa5 100644
--- a/main/src/main/java/st/slex/messenger/main/utilites/base/SetImageWithGlide.kt
+++ b/main/src/main/java/st/slex/messenger/main/utilites/base/SetImageWithGlide.kt
@@ -19,5 +19,4 @@ class SetImageWithGlide(
needCircleCrop: Boolean = false,
needOriginal: Boolean = false
) = makeGlideImage(imageView, url, needCrop, needCircleCrop, needOriginal)
-
}
\ No newline at end of file
diff --git a/main/src/main/res/layout/fragment_chats.xml b/main/src/main/res/layout/fragment_chats.xml
index e60edbf..e21a92f 100644
--- a/main/src/main/res/layout/fragment_chats.xml
+++ b/main/src/main/res/layout/fragment_chats.xml
@@ -3,22 +3,31 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_screen_drawer_layout"
+ style="@style/Widget.Material3.DrawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="st.slex.messenger.main.ui.chats.ChatsFragment">
-
+
+
@@ -34,24 +43,18 @@
-
-
-
-
+
-
\ No newline at end of file
diff --git a/main/src/main/res/layout/fragment_contact.xml b/main/src/main/res/layout/fragment_contact.xml
index b8dc016..9153e49 100644
--- a/main/src/main/res/layout/fragment_contact.xml
+++ b/main/src/main/res/layout/fragment_contact.xml
@@ -12,13 +12,13 @@
android:layout_height="match_parent">
diff --git a/main/src/main/res/layout/fragment_settings.xml b/main/src/main/res/layout/fragment_settings.xml
index 757efe1..f45795c 100644
--- a/main/src/main/res/layout/fragment_settings.xml
+++ b/main/src/main/res/layout/fragment_settings.xml
@@ -1,34 +1,37 @@
+ android:layout_height="wrap_content"
+ app:title="Settings" />
-
-
-
\ No newline at end of file
diff --git a/main/src/main/res/layout/fragment_single_chat.xml b/main/src/main/res/layout/fragment_single_chat.xml
index 0665002..77584b5 100644
--- a/main/src/main/res/layout/fragment_single_chat.xml
+++ b/main/src/main/res/layout/fragment_single_chat.xml
@@ -12,15 +12,15 @@
android:layout_height="match_parent">
+ android:layout_height="?actionBarSize">
+ android:layout_height="?actionBarSize">
@@ -56,30 +56,24 @@
-
-
-
-
-
+ app:layout_constraintStart_toStartOf="parent" />
+ app:layout_constraintTop_toTopOf="@+id/edit_text" />
diff --git a/main/src/main/res/layout/fragment_user_profile.xml b/main/src/main/res/layout/fragment_user_profile.xml
index 27343c0..bed6fb4 100644
--- a/main/src/main/res/layout/fragment_user_profile.xml
+++ b/main/src/main/res/layout/fragment_user_profile.xml
@@ -8,12 +8,12 @@
+ tools:src="@drawable/ic_default_photo" />
-
+ app:layout_constraintTop_toTopOf="parent" />
-
-
\ No newline at end of file
diff --git a/main/src/main/res/layout/item_recycler_single_chat.xml b/main/src/main/res/layout/item_recycler_single_chat.xml
index 9cdc264..f1ca27d 100644
--- a/main/src/main/res/layout/item_recycler_single_chat.xml
+++ b/main/src/main/res/layout/item_recycler_single_chat.xml
@@ -1,95 +1,101 @@
-
-
-
+ android:layout_margin="@dimen/primary_padding"
+ android:orientation="vertical">
-
+
-
+
+
+
-
-
-
+ android:padding="@dimen/primary_padding">
-
+ android:layout_margin="@dimen/primary_padding"
+ android:orientation="vertical">
+
-
+
+
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/main/src/main/res/layout/navigation_drawer_header.xml b/main/src/main/res/layout/navigation_drawer_header.xml
index eeabcee..831cc71 100644
--- a/main/src/main/res/layout/navigation_drawer_header.xml
+++ b/main/src/main/res/layout/navigation_drawer_header.xml
@@ -2,6 +2,7 @@
@@ -20,11 +21,12 @@
android:layout_gravity="bottom|center_horizontal"
android:background="@color/blue_gray_200"
android:orientation="vertical"
- android:padding="4dp">
+ android:padding="4dp"
+ android:paddingStart="@dimen/primary_padding">
-
-
+ tools:layout_height="wrap_content">
-
+
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+ android:ellipsize="end"
+ android:gravity="center"
+ android:lines="1"
+ tools:text="Username" />
+
+
+
+
\ No newline at end of file
diff --git a/main/src/main/res/navigation/nav_graph.xml b/main/src/main/res/navigation/nav_graph.xml
index f1f0125..e92e557 100644
--- a/main/src/main/res/navigation/nav_graph.xml
+++ b/main/src/main/res/navigation/nav_graph.xml
@@ -56,7 +56,7 @@
-
- #FFBB86FC
- #FF6200EE
- #FF3700B3
- #FF03DAC5
- #FF018786
- #121212
- #FFFFFFFF
-
- #90A4AE
- #9890A4AE
-
- #C2FBC5
- #BBDEFB
-
\ No newline at end of file
diff --git a/phoneedittext/build.gradle b/phoneedittext/build.gradle
deleted file mode 100644
index 1e1eb20..0000000
--- a/phoneedittext/build.gradle
+++ /dev/null
@@ -1,41 +0,0 @@
-plugins {
- id("com.android.library")
- id("kotlin-android")
-}
-
-android {
- compileSdk 32
-
- defaultConfig {
- minSdk 21
- targetSdk 32
-
- testInstrumentationRunner("androidx.test.runner.AndroidJUnitRunner")
- consumerProguardFiles("consumer-rules.pro")
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), "proguard-rules.pro"
- }
- }
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
- kotlinOptions {
- jvmTarget = "1.8"
- }
-}
-
-dependencies {
- implementation("androidx.startup:startup-runtime:1.1.1")
- implementation("io.michaelrocks:libphonenumber-android:8.12.33")
- implementation("androidx.core:core-ktx:1.7.0")
- implementation("androidx.appcompat:appcompat:1.4.1")
- implementation("com.google.android.material:material:1.5.0")
- testImplementation("junit:junit:4.13.2")
- androidTestImplementation("androidx.test.ext:junit:1.1.3")
- androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
-}
\ No newline at end of file
diff --git a/phoneedittext/build.gradle.kts b/phoneedittext/build.gradle.kts
new file mode 100644
index 0000000..17fb3ae
--- /dev/null
+++ b/phoneedittext/build.gradle.kts
@@ -0,0 +1,59 @@
+plugins {
+ id("com.android.library")
+ id("kotlin-android")
+}
+
+android {
+ compileSdk = 32
+
+ defaultConfig {
+ minSdk = 21
+ targetSdk = 32
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles("consumer-rules.pro")
+ }
+
+ buildTypes {
+ getByName("release") {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ getByName("debug") {
+ isTestCoverageEnabled = true
+ }
+ }
+
+ testOptions {
+ unitTests {
+ isIncludeAndroidResources = true
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility(JavaVersion.VERSION_11)
+ targetCompatibility(JavaVersion.VERSION_11)
+ }
+
+ sourceSets {
+ getByName("androidTest").assets.srcDir("$projectDir/schemas")
+ }
+
+ kotlinOptions {
+ jvmTarget = "11"
+ }
+}
+
+dependencies {
+ implementation("androidx.startup:startup-runtime:1.1.1")
+ implementation("io.michaelrocks:libphonenumber-android:8.12.33")
+ implementation("androidx.core:core-ktx:1.7.0")
+ implementation("androidx.appcompat:appcompat:1.4.1")
+ implementation("com.google.android.material:material:1.6.0")
+ testImplementation("junit:junit:4.13.2")
+ androidTestImplementation("androidx.test.ext:junit:1.1.3")
+ androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
+}
\ No newline at end of file
diff --git a/phoneedittext/proguard-rules.pro b/phoneedittext/proguard-rules.pro
index 481bb43..ff59496 100644
--- a/phoneedittext/proguard-rules.pro
+++ b/phoneedittext/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/resources/.gitignore b/resources/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/resources/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/resources/build.gradle.kts b/resources/build.gradle.kts
new file mode 100644
index 0000000..e763495
--- /dev/null
+++ b/resources/build.gradle.kts
@@ -0,0 +1,43 @@
+plugins {
+ id("com.android.library")
+ id("org.jetbrains.kotlin.android")
+}
+
+android {
+ compileSdk = 32
+
+ defaultConfig {
+ minSdk = 23
+ targetSdk = 32
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles("consumer-rules.pro")
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+dependencies {
+
+ implementation("androidx.core:core-ktx:1.7.0")
+ implementation("androidx.appcompat:appcompat:1.4.1")
+ implementation("com.google.android.material:material:1.6.0")
+ testImplementation("junit:junit:4.13.2")
+ androidTestImplementation("androidx.test.ext:junit:1.1.3")
+ androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
+}
\ No newline at end of file
diff --git a/resources/consumer-rules.pro b/resources/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/resources/proguard-rules.pro b/resources/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/resources/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/resources/src/androidTest/java/st/slex/resources/ExampleInstrumentedTest.kt b/resources/src/androidTest/java/st/slex/resources/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..6f9b7b8
--- /dev/null
+++ b/resources/src/androidTest/java/st/slex/resources/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package st.slex.resources
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("st.slex.resources.test", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/resources/src/main/AndroidManifest.xml b/resources/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..322ca43
--- /dev/null
+++ b/resources/src/main/AndroidManifest.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/resources/src/main/java/st/slex/resources/KeyboardUtil.kt b/resources/src/main/java/st/slex/resources/KeyboardUtil.kt
new file mode 100644
index 0000000..b83cccb
--- /dev/null
+++ b/resources/src/main/java/st/slex/resources/KeyboardUtil.kt
@@ -0,0 +1,5 @@
+package st.slex.resources
+
+interface KeyboardUtil {
+ fun hideKeyboard()
+}
\ No newline at end of file
diff --git a/resources/src/main/java/st/slex/resources/KeyboardUtilImpl.kt b/resources/src/main/java/st/slex/resources/KeyboardUtilImpl.kt
new file mode 100644
index 0000000..edc548c
--- /dev/null
+++ b/resources/src/main/java/st/slex/resources/KeyboardUtilImpl.kt
@@ -0,0 +1,27 @@
+package st.slex.resources
+
+import android.app.Activity
+import android.content.Context
+import android.view.View
+import android.view.inputmethod.InputMethodManager
+import java.lang.ref.WeakReference
+
+class KeyboardUtilImpl constructor(
+ private val activity: WeakReference
+) : KeyboardUtil {
+
+ private val hidingView: View? by lazy {
+ activity.get()?.currentFocus
+ }
+
+ private val inputMethodManager: InputMethodManager
+ get() = activity.get()?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+
+ override fun hideKeyboard() {
+ inputMethodManager.hideSoftInputFromWindow(hidingView?.windowToken, HIDE_KEYBOARD)
+ }
+
+ companion object {
+ private const val HIDE_KEYBOARD = InputMethodManager.RESULT_UNCHANGED_SHOWN
+ }
+}
\ No newline at end of file
diff --git a/main/src/main/res/values-night/themes.xml b/resources/src/main/res/values-night/theme.xml
similarity index 63%
rename from main/src/main/res/values-night/themes.xml
rename to resources/src/main/res/values-night/theme.xml
index db2d048..8be76d6 100644
--- a/main/src/main/res/values-night/themes.xml
+++ b/resources/src/main/res/values-night/theme.xml
@@ -1,7 +1,7 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/main/src/main/res/values-ru/strings.xml b/resources/src/main/res/values-ru/strings.xml
similarity index 100%
rename from main/src/main/res/values-ru/strings.xml
rename to resources/src/main/res/values-ru/strings.xml
diff --git a/app/src/main/res/values/colors.xml b/resources/src/main/res/values/colors.xml
similarity index 100%
rename from app/src/main/res/values/colors.xml
rename to resources/src/main/res/values/colors.xml
diff --git a/main/src/main/res/values/dimens.xml b/resources/src/main/res/values/dimens.xml
similarity index 100%
rename from main/src/main/res/values/dimens.xml
rename to resources/src/main/res/values/dimens.xml
diff --git a/resources/src/main/res/values/ic_launcher_background.xml b/resources/src/main/res/values/ic_launcher_background.xml
new file mode 100644
index 0000000..1fd6375
--- /dev/null
+++ b/resources/src/main/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #475858
+
\ No newline at end of file
diff --git a/main/src/main/res/values/integers.xml b/resources/src/main/res/values/integers.xml
similarity index 100%
rename from main/src/main/res/values/integers.xml
rename to resources/src/main/res/values/integers.xml
diff --git a/main/src/main/res/values/strings.xml b/resources/src/main/res/values/strings.xml
similarity index 99%
rename from main/src/main/res/values/strings.xml
rename to resources/src/main/res/values/strings.xml
index a30080b..f46826e 100644
--- a/main/src/main/res/values/strings.xml
+++ b/resources/src/main/res/values/strings.xml
@@ -44,5 +44,4 @@
auth_transition_name
change image
change
-
\ No newline at end of file
diff --git a/main/src/main/res/values/themes.xml b/resources/src/main/res/values/theme.xml
similarity index 68%
rename from main/src/main/res/values/themes.xml
rename to resources/src/main/res/values/theme.xml
index 1ba5e45..8441459 100644
--- a/main/src/main/res/values/themes.xml
+++ b/resources/src/main/res/values/theme.xml
@@ -1,7 +1,7 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/resources/src/test/java/st/slex/resources/ExampleUnitTest.kt b/resources/src/test/java/st/slex/resources/ExampleUnitTest.kt
new file mode 100644
index 0000000..4a18028
--- /dev/null
+++ b/resources/src/test/java/st/slex/resources/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package st.slex.resources
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
\ No newline at end of file
diff --git a/settings.gradle.kts b/settings.gradle.kts
index e7fb27a..2a3ed7d 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,7 +1,8 @@
rootProject.name = "Messenger"
include(":app")
-include (":phoneedittext")
-include (":main")
-include (":auth")
-include (":splashscreen")
-include (":core")
+include(":phoneedittext")
+include(":main")
+include(":auth")
+include(":splashscreen")
+include(":core")
+include(":resources")
\ No newline at end of file
diff --git a/splashscreen/build.gradle b/splashscreen/build.gradle
deleted file mode 100644
index c59b10a..0000000
--- a/splashscreen/build.gradle
+++ /dev/null
@@ -1,47 +0,0 @@
-plugins {
- id 'com.android.library'
- id 'kotlin-android'
-}
-
-android {
- compileSdk 31
-
- defaultConfig {
- minSdk 23
- targetSdk 31
-
- testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
- consumerProguardFiles "consumer-rules.pro"
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
- }
- }
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
- kotlinOptions {
- jvmTarget = '1.8'
- }
-}
-
-dependencies {
- /*Firebase*/
- implementation platform('com.google.firebase:firebase-bom:28.4.0')
- implementation 'com.google.firebase:firebase-auth:21.0.1'
- implementation 'com.google.firebase:firebase-auth-ktx'
-
- /*Lifecycle*/
- implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.3.1"
-
- implementation 'androidx.core:core-ktx:1.6.0'
- implementation 'androidx.appcompat:appcompat:1.3.1'
- implementation 'com.google.android.material:material:1.4.0'
- testImplementation 'junit:junit:4.+'
- androidTestImplementation 'androidx.test.ext:junit:1.1.3'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
-}
\ No newline at end of file
diff --git a/splashscreen/build.gradle.kts b/splashscreen/build.gradle.kts
new file mode 100644
index 0000000..fabc261
--- /dev/null
+++ b/splashscreen/build.gradle.kts
@@ -0,0 +1,65 @@
+plugins {
+ id("com.android.library")
+ id("kotlin-android")
+}
+
+android {
+ compileSdk = 32
+
+ defaultConfig {
+ minSdk = 23
+ targetSdk = 32
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles("consumer-rules.pro")
+ }
+
+ buildTypes {
+ getByName("release") {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ getByName("debug") {
+ isTestCoverageEnabled = true
+ }
+ }
+
+ testOptions {
+ unitTests {
+ isIncludeAndroidResources = true
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility(JavaVersion.VERSION_11)
+ targetCompatibility(JavaVersion.VERSION_11)
+ }
+
+ sourceSets {
+ getByName("androidTest").assets.srcDir("$projectDir/schemas")
+ }
+
+ kotlinOptions {
+ jvmTarget = "11"
+ }
+}
+
+dependencies {
+ /*Firebase*/
+ implementation(platform("com.google.firebase:firebase-bom:28.4.0"))
+ implementation("com.google.firebase:firebase-auth:21.0.3")
+ implementation("com.google.firebase:firebase-auth-ktx")
+
+ /*Lifecycle*/
+ implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.4.1")
+
+ implementation("androidx.core:core-ktx:1.7.0")
+ implementation("androidx.appcompat:appcompat:1.4.1")
+ implementation("com.google.android.material:material:1.6.0")
+ testImplementation("junit:junit:4.13.2")
+ androidTestImplementation("androidx.test.ext:junit:1.1.3")
+ androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
+}
\ No newline at end of file
diff --git a/splashscreen/proguard-rules.pro b/splashscreen/proguard-rules.pro
index 481bb43..ff59496 100644
--- a/splashscreen/proguard-rules.pro
+++ b/splashscreen/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/splashscreen/src/main/res/drawable/ic_launcher_foreground.xml b/splashscreen/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..e387ec6
--- /dev/null
+++ b/splashscreen/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/splash_screen.xml b/splashscreen/src/main/res/drawable/splash_screen.xml
similarity index 99%
rename from app/src/main/res/drawable/splash_screen.xml
rename to splashscreen/src/main/res/drawable/splash_screen.xml
index eef9ee4..0458c5e 100644
--- a/app/src/main/res/drawable/splash_screen.xml
+++ b/splashscreen/src/main/res/drawable/splash_screen.xml
@@ -5,5 +5,4 @@
-
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/splashscreen/src/main/res/values-night/styles.xml
similarity index 66%
rename from app/src/main/res/values/styles.xml
rename to splashscreen/src/main/res/values-night/styles.xml
index 7d5cc8f..8fcd778 100644
--- a/app/src/main/res/values/styles.xml
+++ b/splashscreen/src/main/res/values-night/styles.xml
@@ -1,7 +1,7 @@
-
\ No newline at end of file
diff --git a/splashscreen/src/main/res/values/colors.xml b/splashscreen/src/main/res/values/colors.xml
new file mode 100644
index 0000000..0fff84d
--- /dev/null
+++ b/splashscreen/src/main/res/values/colors.xml
@@ -0,0 +1,4 @@
+
+
+ #9890A4AE
+
\ No newline at end of file
diff --git a/splashscreen/src/main/res/values/styles.xml b/splashscreen/src/main/res/values/styles.xml
new file mode 100644
index 0000000..2de6f90
--- /dev/null
+++ b/splashscreen/src/main/res/values/styles.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file