diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 22cfacb..273d0ce 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -67,6 +67,15 @@ dependencies {
// retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
- implementation 'com.squareup.retrofit2:converter-gson:2.6.0'
+ implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.8.0'
+
+ // Gson
+ implementation "com.google.code.gson:gson:2.8.6"
+
+ // Kotlin Android Coroutines
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0'
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0"
+ implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
+
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0fdd82b..164e8fe 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,6 +6,7 @@
: Fragment() {
+
+
+ //Binding View
+ private var _binding: ViewBinding? = null
+ abstract val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> T
+
+ //this will be used in child classes
+ protected val binding: T
+ get() = _binding as T
+
+
+ lateinit var mDialog: Dialog
+ fun showProgressDialog(context: Context) {
+ mDialog = Dialog(context)
+ mDialog.setContentView(R.layout.fragment_base)
+ mDialog.show()
+ }
+
+ fun hideProgressDialog() {
+ mDialog.dismiss()
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = bindingInflater.invoke(layoutInflater, container, false)
+ return _binding!!.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setupOnViewCreated(view)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ _binding = null
+ hideProgressDialog()
+ }
+
+
+ //Implemented into the child class
+ abstract fun setupOnViewCreated(view: View)
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ahmed/contactbook/MyApp.kt b/app/src/main/java/com/ahmed/contactbook/MyApp.kt
new file mode 100644
index 0000000..e12aec9
--- /dev/null
+++ b/app/src/main/java/com/ahmed/contactbook/MyApp.kt
@@ -0,0 +1,15 @@
+package com.ahmed.contactbook
+
+import android.app.Application
+import android.content.Context
+
+class MyApp:Application() {
+
+ override fun onCreate() {
+ super.onCreate()
+ appContext =applicationContext
+ }
+companion object{
+ lateinit var appContext: Context
+}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ahmed/contactbook/data/db/UserDao.kt b/app/src/main/java/com/ahmed/contactbook/data/db/UserDao.kt
index fd2f981..bc0f4a6 100644
--- a/app/src/main/java/com/ahmed/contactbook/data/db/UserDao.kt
+++ b/app/src/main/java/com/ahmed/contactbook/data/db/UserDao.kt
@@ -1,3 +1,6 @@
+
+
+
package com.ahmed.contactbook.data.db
import androidx.room.Dao
diff --git a/app/src/main/java/com/ahmed/contactbook/data/model/LoginResponse.kt b/app/src/main/java/com/ahmed/contactbook/data/model/LoginResponse.kt
index 8a177e7..55b5f60 100644
--- a/app/src/main/java/com/ahmed/contactbook/data/model/LoginResponse.kt
+++ b/app/src/main/java/com/ahmed/contactbook/data/model/LoginResponse.kt
@@ -1,3 +1,3 @@
package com.ahmed.contactbook.data.model
-data class LoginResponse (var toekn:String)
\ No newline at end of file
+data class LoginResponse (var token:String)
\ No newline at end of file
diff --git a/app/src/main/java/com/ahmed/contactbook/data/model/UserRegister.kt b/app/src/main/java/com/ahmed/contactbook/data/model/UserRegister.kt
new file mode 100644
index 0000000..ce82e6d
--- /dev/null
+++ b/app/src/main/java/com/ahmed/contactbook/data/model/UserRegister.kt
@@ -0,0 +1,7 @@
+package com.ahmed.contactbook.data.model
+
+data class UserRegister(
+ var name:String,
+ var email:String,
+ var password:String
+)
diff --git a/app/src/main/java/com/ahmed/contactbook/data/remote/ApiSettings.kt b/app/src/main/java/com/ahmed/contactbook/data/remote/ApiSettings.kt
index c206f2c..0fc5b61 100644
--- a/app/src/main/java/com/ahmed/contactbook/data/remote/ApiSettings.kt
+++ b/app/src/main/java/com/ahmed/contactbook/data/remote/ApiSettings.kt
@@ -1,5 +1,6 @@
package com.ahmed.contactbook.data.remote
+import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
@@ -15,6 +16,7 @@ object ApiSettings {
Retrofit.Builder()
.baseUrl("https://phonebook-be.herokuapp.com/api/")
.client(client)
+ .addCallAdapterFactory(CoroutineCallAdapterFactory())
.addConverterFactory(GsonConverterFactory.create())
.build()
}
diff --git a/app/src/main/java/com/ahmed/contactbook/data/remote/ContactApi.kt b/app/src/main/java/com/ahmed/contactbook/data/remote/ContactApi.kt
index 35b6464..cc1207a 100644
--- a/app/src/main/java/com/ahmed/contactbook/data/remote/ContactApi.kt
+++ b/app/src/main/java/com/ahmed/contactbook/data/remote/ContactApi.kt
@@ -2,14 +2,20 @@ package com.ahmed.contactbook.data.remote
import com.ahmed.contactbook.data.model.LoginResponse
import com.ahmed.contactbook.data.model.UserData
-import retrofit2.Call
+import com.ahmed.contactbook.data.model.UserRegister
+import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.POST
interface ContactApi {
@POST("login")
- fun loginUser(
+ suspend fun loginUser(
@Body user: UserData
- ): Call
+ ): Response
+
+ @POST("register")
+ suspend fun registerUser(
+ @Body user: UserRegister
+ ): Response
}
\ No newline at end of file
diff --git a/app/src/main/java/com/ahmed/contactbook/data/repo/Repo.kt b/app/src/main/java/com/ahmed/contactbook/data/repo/Repo.kt
index dce40c3..9733b40 100644
--- a/app/src/main/java/com/ahmed/contactbook/data/repo/Repo.kt
+++ b/app/src/main/java/com/ahmed/contactbook/data/repo/Repo.kt
@@ -1,42 +1,16 @@
package com.ahmed.contactbook.data.repo
-import android.util.Log
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
import com.ahmed.contactbook.data.model.LoginResponse
import com.ahmed.contactbook.data.model.UserData
+import com.ahmed.contactbook.data.model.UserRegister
import com.ahmed.contactbook.data.remote.ApiSettings
-import retrofit2.Call
-import retrofit2.Callback
import retrofit2.Response
class Repo {
- val liveData: MutableLiveData = MutableLiveData()
- fun loginUser(email: String, password: String): LiveData {
- val user = UserData(email, password)
- ApiSettings.apiInstance.loginUser(user)
- .enqueue(object : Callback {
- override fun onResponse(
- call: Call,
- response: Response
- ) {
-
- try {
- if (response.isSuccessful)
- liveData.value = response.body()!!.toString() + "01097203910"
- else
- liveData.value = response.message()
- } catch (t: Exception) {
- Log.d("error", response.errorBody().toString())
- }
- }
- override fun onFailure(call: Call, t: Throwable) {
- liveData.value = t.message
- Log.d("Error", t.message.toString())
- }
+ suspend fun loginUser(user: UserData): Response =
+ ApiSettings.apiInstance.loginUser(user)
- })
- return liveData
- }
+ suspend fun registerUser(user: UserRegister): Response =
+ ApiSettings.apiInstance.registerUser(user)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/ahmed/contactbook/ui/home/HomeFragment.kt b/app/src/main/java/com/ahmed/contactbook/ui/home/HomeFragment.kt
new file mode 100644
index 0000000..b824c65
--- /dev/null
+++ b/app/src/main/java/com/ahmed/contactbook/ui/home/HomeFragment.kt
@@ -0,0 +1,22 @@
+package com.ahmed.contactbook.ui.home
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.lifecycle.ViewModelProvider
+import com.ahmed.contactbook.BaseFragment
+import com.ahmed.contactbook.databinding.HomeFragmentBinding
+
+class HomeFragment : BaseFragment() {
+
+
+ private lateinit var viewModel: HomeViewModel
+ override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> HomeFragmentBinding
+ get() = HomeFragmentBinding::inflate
+
+ override fun setupOnViewCreated(view: View) {
+ viewModel = ViewModelProvider(this).get(HomeViewModel::class.java)
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ahmed/contactbook/ui/home/HomeViewModel.kt b/app/src/main/java/com/ahmed/contactbook/ui/home/HomeViewModel.kt
new file mode 100644
index 0000000..fd49acb
--- /dev/null
+++ b/app/src/main/java/com/ahmed/contactbook/ui/home/HomeViewModel.kt
@@ -0,0 +1,7 @@
+package com.ahmed.contactbook.ui.home
+
+import androidx.lifecycle.ViewModel
+
+class HomeViewModel : ViewModel() {
+ // TODO: Implement the ViewModel
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ahmed/contactbook/ui/login/AuthListener.kt b/app/src/main/java/com/ahmed/contactbook/ui/login/AuthListener.kt
index 8fa52b1..8150327 100644
--- a/app/src/main/java/com/ahmed/contactbook/ui/login/AuthListener.kt
+++ b/app/src/main/java/com/ahmed/contactbook/ui/login/AuthListener.kt
@@ -4,7 +4,7 @@ import androidx.lifecycle.LiveData
interface AuthListener {
fun onStarted()
- fun onSuccess(liveData: LiveData)
+ fun onSuccess()
fun onFailure(msg:String)
fun isConnection():Boolean
}
\ No newline at end of file
diff --git a/app/src/main/java/com/ahmed/contactbook/ui/login/LoginFragment.kt b/app/src/main/java/com/ahmed/contactbook/ui/login/LoginFragment.kt
index 4c72e8e..604d7c8 100644
--- a/app/src/main/java/com/ahmed/contactbook/ui/login/LoginFragment.kt
+++ b/app/src/main/java/com/ahmed/contactbook/ui/login/LoginFragment.kt
@@ -1,53 +1,55 @@
package com.ahmed.contactbook.ui.login
-import android.os.Bundle
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
import android.widget.Toast
-import androidx.fragment.app.Fragment
-import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModelProvider
+import androidx.navigation.NavController
+import androidx.navigation.Navigation
+import com.ahmed.contactbook.BaseFragment
import com.ahmed.contactbook.R
import com.ahmed.contactbook.databinding.LoginFragmentBinding
import com.ahmed.contactbook.utils.ChechInternetConnection
-class LoginFragment : Fragment(R.layout.login_fragment), AuthListener {
- lateinit var binding: LoginFragmentBinding
- lateinit var viewModel: LoginViewModel
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- binding = LoginFragmentBinding.bind(view)
- viewModel = ViewModelProvider(requireActivity()).get(LoginViewModel::class.java)
+class LoginFragment : BaseFragment(), AuthListener {
+ private lateinit var viewModel: LoginViewModel
+ private lateinit var navController: NavController
+ override fun setupOnViewCreated(view: View) {
+ viewModel = ViewModelProvider(requireActivity()).get(LoginViewModel::class.java)
+ navController = Navigation.findNavController(view)
viewModel.authListener = this
binding.btnLogin.setOnClickListener {
val email = binding.etEmail.text.toString()
val password = binding.etPassword.text.toString()
viewModel.sendLoginRequest(email, password)
}
-
+ binding.tvRegister.setOnClickListener { navController.navigate(R.id.action_loginFragment_to_registerFragment) }
}
override fun onStarted() {
- Toast.makeText(requireContext(), "started", Toast.LENGTH_SHORT).show()
- binding.progressBar.visibility = View.VISIBLE
-
+ showProgressDialog(requireContext())
}
- override fun onSuccess(liveData: LiveData) {
- liveData.observe(requireActivity(), { result ->
- Toast.makeText(requireContext(), result, Toast.LENGTH_SHORT).show()
- })
- binding.progressBar.visibility = View.GONE
+ override fun onSuccess() {
+ hideProgressDialog()
+ navController.navigate(R.id.action_loginFragment_to_homeFragment)
}
override fun onFailure(msg: String) {
+ hideProgressDialog()
Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT).show()
- binding.progressBar.visibility = View.GONE
+
}
override fun isConnection(): Boolean {
return ChechInternetConnection(requireContext()).isConnection()
}
+ override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> LoginFragmentBinding
+ get() = LoginFragmentBinding::inflate
+
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/ahmed/contactbook/ui/login/LoginViewModel.kt b/app/src/main/java/com/ahmed/contactbook/ui/login/LoginViewModel.kt
index f1184a3..d37d1ab 100644
--- a/app/src/main/java/com/ahmed/contactbook/ui/login/LoginViewModel.kt
+++ b/app/src/main/java/com/ahmed/contactbook/ui/login/LoginViewModel.kt
@@ -2,11 +2,11 @@ package com.ahmed.contactbook.ui.login
import android.util.Log
import android.util.Patterns
-import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.ahmed.contactbook.data.repo.Repo
-import kotlinx.coroutines.Dispatchers
+import com.ahmed.contactbook.utils.ContactBookPreferences
+import com.ahmed.contactbook.utils.SharedKeyEnum
import kotlinx.coroutines.launch
@@ -16,33 +16,38 @@ class LoginViewModel : ViewModel() {
fun sendLoginRequest(email: String, password: String) {
if (authListener!!.isConnection()) {
- if (email.isEmpty()) {
- authListener!!.onFailure("Please Enter Your Email Address")
- return
- }
- if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
- authListener!!.onFailure("Please add valid email")
- return
- }
- if (password.isEmpty()) {
- authListener!!.onFailure("Please add your password")
+
+ if (email.isEmpty() || !Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
+ authListener!!.onFailure("Please Enter Valid Email Address")
return
}
-
- if (password.length < 6) {
- authListener!!.onFailure("password must be 6 char")
+ if (password.isEmpty() || password.length < 6) {
+ authListener!!.onFailure("password must be more than 6 characters")
return
}
+
authListener!!.onStarted()
try {
-
- val repository: LiveData =
- Repo().loginUser(email, password)
- authListener!!.onSuccess(repository)
-
+ val user = com.ahmed.contactbook.data.model.UserData(email, password)
+ viewModelScope.launch {
+
+ val request = Repo().loginUser(user)
+ if (request.isSuccessful) {
+ val token = request.body()!!.token
+
+ ContactBookPreferences().setString(SharedKeyEnum.TOKEN.toString(), token)
+ ContactBookPreferences().setBoolean(
+ SharedKeyEnum.FIRST_LOGIN.toString(),
+ false
+ )
+ authListener!!.onSuccess()
+ } else {
+ authListener?.onFailure("email or password isn't correct")
+ }
+ }
} catch (ex: Exception) {
diff --git a/app/src/main/java/com/ahmed/contactbook/ui/register/RegisterFragment.kt b/app/src/main/java/com/ahmed/contactbook/ui/register/RegisterFragment.kt
new file mode 100644
index 0000000..20fe808
--- /dev/null
+++ b/app/src/main/java/com/ahmed/contactbook/ui/register/RegisterFragment.kt
@@ -0,0 +1,56 @@
+package com.ahmed.contactbook.ui.register
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Toast
+import androidx.lifecycle.ViewModelProvider
+import androidx.navigation.NavController
+import androidx.navigation.Navigation
+import com.ahmed.contactbook.BaseFragment
+import com.ahmed.contactbook.R
+import com.ahmed.contactbook.databinding.RegisterFragmentBinding
+import com.ahmed.contactbook.ui.login.AuthListener
+import com.ahmed.contactbook.utils.ChechInternetConnection
+
+class RegisterFragment : BaseFragment(), AuthListener {
+
+ private lateinit var viewModel: RegisterViewModel
+ private lateinit var navController: NavController
+ override fun onStarted() {
+ showProgressDialog(requireContext())
+ }
+
+ override fun onSuccess() {
+ hideProgressDialog()
+ navController.navigate(R.id.action_registerFragment_to_homeFragment)
+ }
+
+ override fun onFailure(msg: String) {
+ hideProgressDialog()
+ Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT).show()
+ }
+
+ override fun isConnection(): Boolean {
+ return ChechInternetConnection(requireContext()).isConnection()
+ }
+
+ override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> RegisterFragmentBinding
+ get() = RegisterFragmentBinding::inflate
+
+ override fun setupOnViewCreated(view: View) {
+ viewModel = ViewModelProvider(
+ this
+ ).get(RegisterViewModel::class.java)
+ viewModel.authListener = this
+ navController = Navigation.findNavController(view)
+ binding.btnLogin.setOnClickListener {
+ val name = binding.etName.text.toString()
+ val email = binding.etEmail.text.toString()
+ val password = binding.etPassword.text.toString()
+ viewModel.sendRegisterRequest(name, email, password)
+
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ahmed/contactbook/ui/register/RegisterViewModel.kt b/app/src/main/java/com/ahmed/contactbook/ui/register/RegisterViewModel.kt
new file mode 100644
index 0000000..b9640f3
--- /dev/null
+++ b/app/src/main/java/com/ahmed/contactbook/ui/register/RegisterViewModel.kt
@@ -0,0 +1,63 @@
+package com.ahmed.contactbook.ui.register
+
+import android.util.Log
+import android.util.Patterns
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.ahmed.contactbook.data.model.UserRegister
+import com.ahmed.contactbook.data.repo.Repo
+import com.ahmed.contactbook.ui.login.AuthListener
+import com.ahmed.contactbook.utils.ContactBookPreferences
+import com.ahmed.contactbook.utils.SharedKeyEnum
+import kotlinx.coroutines.launch
+
+class RegisterViewModel : ViewModel() {
+ var authListener: AuthListener? = null
+
+ fun sendRegisterRequest(name: String, email: String, password: String) {
+ if (authListener!!.isConnection()) {
+ if (name.isEmpty()) {
+ authListener!!.onFailure("Please Enter Your Name")
+ return
+ }
+ if (email.isEmpty() || !Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
+ authListener!!.onFailure("Please Enter Valid Email Address")
+ return
+ }
+
+ if (password.isEmpty() ||password.length < 6) {
+ authListener!!.onFailure("password must be more than 6 characters")
+ return
+ }
+
+ authListener!!.onStarted()
+
+ try {
+ val userRegister = UserRegister(name, email, password)
+ viewModelScope.launch {
+
+ val request = Repo().registerUser(userRegister)
+ if (request.isSuccessful) {
+ val token = request.body()!!.token
+ ContactBookPreferences().setString(SharedKeyEnum.TOKEN.toString(), token)
+ ContactBookPreferences().setBoolean(
+ SharedKeyEnum.FIRST_LOGIN.toString(),
+ true
+ )
+ authListener!!.onSuccess()
+ } else authListener!!.onFailure("Failed To Register")
+
+ }
+
+
+ } catch (ex: Exception) {
+ Log.d("viewmodel", ex.message.toString())
+ authListener!!.onFailure("Failed To Register")
+ }
+
+
+ } else
+ authListener!!.onFailure("No Internet Connection")
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ahmed/contactbook/ui/splash/SplashScreen.kt b/app/src/main/java/com/ahmed/contactbook/ui/splash/SplashScreen.kt
index ce6eb47..4e1ad89 100644
--- a/app/src/main/java/com/ahmed/contactbook/ui/splash/SplashScreen.kt
+++ b/app/src/main/java/com/ahmed/contactbook/ui/splash/SplashScreen.kt
@@ -1,32 +1,42 @@
package com.ahmed.contactbook.ui.splash
-import android.os.Bundle
import android.os.Handler
+import android.view.LayoutInflater
import android.view.View
+import android.view.ViewGroup
import android.view.animation.AnimationUtils
-import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.Navigation
+import com.ahmed.contactbook.BaseFragment
import com.ahmed.contactbook.R
import com.ahmed.contactbook.databinding.FragmentSplashScreenBinding
+import com.ahmed.contactbook.utils.ContactBookPreferences
+import com.ahmed.contactbook.utils.SharedKeyEnum
+
+
+class SplashScreen : BaseFragment() {
-class SplashScreen : Fragment(R.layout.fragment_splash_screen) {
- lateinit var binding: FragmentSplashScreenBinding
lateinit var navController: NavController
+ override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentSplashScreenBinding
+ get() = FragmentSplashScreenBinding::inflate
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- binding = FragmentSplashScreenBinding.bind(view)
+ override fun setupOnViewCreated(view: View) {
navController = Navigation.findNavController(view)
val animation = AnimationUtils.loadAnimation(requireContext(), R.anim.bottom_animation)
binding.ivAppIcon.animation = animation
-
+ val token =
+ ContactBookPreferences().getString(SharedKeyEnum.TOKEN.toString())
Handler().postDelayed({
- navController.navigate(R.id.action_splashScreen_to_loginFragment)
- }, 1000)
+ if (!token.isNullOrEmpty())
+ navController.navigate(R.id.action_splashScreen_to_homeFragment)
+ else
+ navController.navigate(R.id.action_splashScreen_to_loginFragment)
+
+ }, 1000)
}
diff --git a/app/src/main/java/com/ahmed/contactbook/utils/ContactBookPreferences.kt b/app/src/main/java/com/ahmed/contactbook/utils/ContactBookPreferences.kt
new file mode 100644
index 0000000..36f2804
--- /dev/null
+++ b/app/src/main/java/com/ahmed/contactbook/utils/ContactBookPreferences.kt
@@ -0,0 +1,65 @@
+package com.ahmed.contactbook.utils
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.content.SharedPreferences
+import com.ahmed.contactbook.MyApp
+
+class ContactBookPreferences {
+
+ var contactBookPreferences: SharedPreferences? = null
+ var editor: SharedPreferences.Editor? = null
+
+ @SuppressLint("CommitPrefEdits")
+ private fun openConnection() {
+ contactBookPreferences = MyApp.appContext.getSharedPreferences(
+ APP_PREFERENCES,
+ Context.MODE_PRIVATE
+ )
+ editor = contactBookPreferences!!.edit()
+ }
+
+ private fun closeConnection() {
+ contactBookPreferences = null
+ editor = null
+ }
+
+ fun setString(key: String?, value: String?) {
+ openConnection()
+ editor!!.putString(key, value)
+ editor!!.commit()
+ closeConnection()
+ }
+
+ fun getString(key: String?): String? {
+ var result: String? = ""
+ openConnection()
+ if (contactBookPreferences?.contains(key) == true) {
+ result = contactBookPreferences?.getString(key,"")
+
+ }
+ closeConnection()
+ return result
+ }
+
+ fun setBoolean(key: String, defValue: Boolean) {
+ openConnection()
+ editor!!.putBoolean(key, defValue)
+ editor!!.commit()
+ closeConnection()
+ }
+
+ fun getBoolean(key: String, defValue: Boolean): Boolean {
+ var result = defValue
+ openConnection()
+ if (contactBookPreferences!!.contains(key)) {
+ result = contactBookPreferences!!.getBoolean(key, defValue)
+ }
+ closeConnection()
+ return result
+ }
+
+ companion object {
+ const val APP_PREFERENCES = "ContactBookPreferences"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ahmed/contactbook/utils/Utils.kt b/app/src/main/java/com/ahmed/contactbook/utils/Utils.kt
new file mode 100644
index 0000000..a333212
--- /dev/null
+++ b/app/src/main/java/com/ahmed/contactbook/utils/Utils.kt
@@ -0,0 +1,6 @@
+package com.ahmed.contactbook.utils
+
+enum class SharedKeyEnum{
+ TOKEN,
+ FIRST_LOGIN
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_base.xml b/app/src/main/res/layout/fragment_base.xml
new file mode 100644
index 0000000..5c85e37
--- /dev/null
+++ b/app/src/main/res/layout/fragment_base.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/home_fragment.xml b/app/src/main/res/layout/home_fragment.xml
new file mode 100644
index 0000000..d83b77c
--- /dev/null
+++ b/app/src/main/res/layout/home_fragment.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/login_fragment.xml b/app/src/main/res/layout/login_fragment.xml
index 120415f..5e229e9 100644
--- a/app/src/main/res/layout/login_fragment.xml
+++ b/app/src/main/res/layout/login_fragment.xml
@@ -34,11 +34,9 @@
android:textSize="24sp" />
+ android:layout_height="wrap_content">
+ android:layout_height="wrap_content">
+
+
+ android:layout_height="wrap_content"
+ android:visibility="gone" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/register_fragment.xml b/app/src/main/res/layout/register_fragment.xml
new file mode 100644
index 0000000..2ef2e71
--- /dev/null
+++ b/app/src/main/res/layout/register_fragment.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/navigation/main_nav.xml b/app/src/main/res/navigation/main_nav.xml
index 23e0ba6..87eb9f7 100644
--- a/app/src/main/res/navigation/main_nav.xml
+++ b/app/src/main/res/navigation/main_nav.xml
@@ -13,10 +13,34 @@
+
+ tools:layout="@layout/login_fragment" >
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 71ef0e9..35d7a4b 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -9,4 +9,5 @@
#FFFFFFFF
#3C3A49
#9500EF
+ #F6F6F6
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..a984995
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+
+
+ 30dp
+ 20sp
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a326fce..9b217bc 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -7,4 +7,7 @@
Email
Password
Login
+ Name
+ Register
+ من فضلك انتظر
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 995cf27..d0c044f 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -13,4 +13,16 @@
- ?attr/colorPrimaryVariant
+
+
+
\ No newline at end of file