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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +