From 2ed8b02a34b2282ac04b1950c3639f18e74b40b6 Mon Sep 17 00:00:00 2001 From: mohamedshasho Date: Sat, 12 Aug 2023 23:35:59 +0300 Subject: [PATCH] fix navigation --- app/build.gradle | 2 +- .../scholar/center/adapter/CategoryAdapter.kt | 17 ++---- .../center/ui/auth/login/LoginFragment.kt | 37 +++++++++++-- .../scholar/center/ui/auth/login/LoginVM.kt | 14 +++-- .../ui/auth/register/RegisterFragment.kt | 19 ++++--- .../center/ui/auth/register/RegisterVM.kt | 8 ++- .../scholar/center/ui/home/HomeFragment.kt | 2 +- .../center/ui/{ => main}/MainFragment.kt | 30 +++++++---- .../java/com/scholar/center/ui/main/MainVM.kt | 32 ++++++++++++ .../center/ui/setting/SettingsFragment.kt | 11 ++-- .../center/ui/stories/StoriesFragment.kt | 2 +- .../center/ui/teachers/TeachersFragment.kt | 3 +- .../java/com/scholar/center/unit/Constants.kt | 1 + .../com/scholar/center/unit/ExtensionFun.kt | 13 +++++ app/src/main/res/layout/fragment_login.xml | 52 ++++++------------- app/src/main/res/layout/fragment_main.xml | 5 +- .../main/res/navigation/root_nav_graph.xml | 44 ++++++++++------ app/src/main/res/values-ar/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + .../scholar/data/repo/AuthRepositoryImp.kt | 15 ++++-- .../scholar/data/repo/StudentRepositoryImp.kt | 14 +++++ .../data/source/local/dao/StudentDao.kt | 8 +++ .../main/java/com/scholar/di/DataModule.kt | 9 +++- .../com/scholar/domain/repo/AuthRepository.kt | 5 +- .../domain/repo/DataStorePreference.kt | 2 +- .../scholar/domain/repo/StudentRepository.kt | 11 ++++ 26 files changed, 246 insertions(+), 114 deletions(-) rename app/src/main/java/com/scholar/center/ui/{ => main}/MainFragment.kt (65%) create mode 100644 app/src/main/java/com/scholar/center/ui/main/MainVM.kt create mode 100644 data/src/main/java/com/scholar/data/repo/StudentRepositoryImp.kt create mode 100644 domain/src/main/java/com/scholar/domain/repo/StudentRepository.kt diff --git a/app/build.gradle b/app/build.gradle index f92db4b..190fe20 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,7 +76,7 @@ dependencies { implementation 'de.hdodenhof:circleimageview:3.1.0' //DataStore - implementation("androidx.datastore:datastore-preferences:1.0.0") + implementation("androidx.datastore:datastore-preferences:1.0.0")// todo try to delete this //Splash Screen implementation("androidx.core:core-splashscreen:1.0.1") diff --git a/app/src/main/java/com/scholar/center/adapter/CategoryAdapter.kt b/app/src/main/java/com/scholar/center/adapter/CategoryAdapter.kt index 15a65f2..b3bb84d 100644 --- a/app/src/main/java/com/scholar/center/adapter/CategoryAdapter.kt +++ b/app/src/main/java/com/scholar/center/adapter/CategoryAdapter.kt @@ -7,6 +7,7 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.scholar.center.R import com.scholar.center.databinding.CategoryItemBinding +import com.scholar.center.unit.getThemeColor import com.scholar.domain.model.Category import com.google.android.material.R.attr as theme @@ -30,14 +31,12 @@ class CategoryAdapter( onClick?.invoke(position) } if (itemSelected == position) { - val selectedColor = getThemeColor( - holder.itemView.context, + val selectedColor = holder.itemView.context.getThemeColor( theme.colorSecondaryVariant ) holder.binding.categoryItemCard.setCardBackgroundColor(selectedColor) } else { - val unSelectedColor = getThemeColor( - holder.itemView.context, + val unSelectedColor = holder.itemView.context.getThemeColor( theme.colorPrimaryContainer ) holder.binding.categoryItemCard.setCardBackgroundColor(unSelectedColor) @@ -62,15 +61,7 @@ class CategoryAdapter( */ } - private fun getThemeColor(context: Context, resId: Int): Int { - val typedValue = TypedValue() - context.theme.resolveAttribute( - resId, - typedValue, - true - ) - return typedValue.data - } + fun setItemSelected(position: Int) { val previousSelected = itemSelected diff --git a/app/src/main/java/com/scholar/center/ui/auth/login/LoginFragment.kt b/app/src/main/java/com/scholar/center/ui/auth/login/LoginFragment.kt index 2238a83..7628f69 100644 --- a/app/src/main/java/com/scholar/center/ui/auth/login/LoginFragment.kt +++ b/app/src/main/java/com/scholar/center/ui/auth/login/LoginFragment.kt @@ -1,9 +1,11 @@ package com.scholar.center.ui.auth.login import android.os.Bundle +import android.text.Spannable +import android.text.SpannableString +import android.text.style.ForegroundColorSpan import android.view.View import android.view.animation.AlphaAnimation -import android.widget.Toast import androidx.core.widget.addTextChangedListener import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels @@ -13,9 +15,11 @@ import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.fragment.findNavController import com.scholar.center.R import com.scholar.center.databinding.FragmentLoginBinding +import com.scholar.center.unit.Constants.MUST_POP_BACK_KEY +import com.scholar.center.unit.getThemeColor import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch - +import com.google.android.material.R.attr as theme @AndroidEntryPoint class LoginFragment : Fragment(R.layout.fragment_login) { @@ -26,6 +30,21 @@ class LoginFragment : Fragment(R.layout.fragment_login) { binding = FragmentLoginBinding.bind(view) + val mustPopBackStack = arguments?.getBoolean(MUST_POP_BACK_KEY) ?: false + + val text = getString(R.string.welcome) + val colorPrimaryContainer = requireContext().getThemeColor( + theme.colorPrimary + ) + val spannable = SpannableString(text) + spannable.setSpan( + ForegroundColorSpan(colorPrimaryContainer), + 0, text.split(" ").first().length, + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE + ) + + binding.loginFragmentWelcomeText.text = spannable + val navController = findNavController() @@ -35,7 +54,11 @@ class LoginFragment : Fragment(R.layout.fragment_login) { val isLoginDestination = navController.currentDestination?.id == R.id.loginFragment //to ensure that navigate call once if (state.isSuccessfullyLogin && isLoginDestination) { - navController.navigate(LoginFragmentDirections.actionLoginToMain()) + if (mustPopBackStack) { + navController.popBackStack() + } else { + navController.navigate(LoginFragmentDirections.actionLoginToMain()) + } } binding.loginFragmentProgressBar.visibility = if (state.isLoading) View.VISIBLE else View.GONE @@ -60,10 +83,14 @@ class LoginFragment : Fragment(R.layout.fragment_login) { viewModel.onPasswordInputChanged(it.toString()) } binding.loginFragmentNoAccount.setOnClickListener { - navController.navigate(LoginFragmentDirections.actionLoginToRegister()) + navController.navigate(LoginFragmentDirections.actionLoginToRegister(mustPopBackStack)) } binding.loginFragmentSkipLayout.setOnClickListener { - navController.navigate(LoginFragmentDirections.actionLoginToMain()) + if (mustPopBackStack) { + navController.popBackStack() + } else { + navController.navigate(LoginFragmentDirections.actionLoginToMain()) + } } } diff --git a/app/src/main/java/com/scholar/center/ui/auth/login/LoginVM.kt b/app/src/main/java/com/scholar/center/ui/auth/login/LoginVM.kt index d7ffebd..9b3f42b 100644 --- a/app/src/main/java/com/scholar/center/ui/auth/login/LoginVM.kt +++ b/app/src/main/java/com/scholar/center/ui/auth/login/LoginVM.kt @@ -7,6 +7,7 @@ import com.scholar.domain.model.LoginInputValidationType import com.scholar.domain.model.LoginState import com.scholar.domain.model.Resource import com.scholar.domain.repo.AuthRepository +import com.scholar.domain.repo.DataStorePreference import com.scholar.domain.usecase.ValidateLoginUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow @@ -16,6 +17,7 @@ import javax.inject.Inject @HiltViewModel class LoginVM @Inject constructor( + private val dataStore: DataStorePreference, private val authRepository: AuthRepository, private val validateLoginUseCase: ValidateLoginUseCase, ) : ViewModel() { @@ -65,17 +67,21 @@ class LoginVM @Inject constructor( ) when (result) { is Resource.Success -> { - result.data?.let { user -> -// dataStoreRepository.saveUser(user) + result.data?.let { studentID -> + dataStore.saveValue(DataStorePreference.userId, studentID) + dataStore.saveValue(DataStorePreference.isUserLoggedIn, true) loginState.update { currentState -> - currentState.copy(isSuccessfullyLogin = true,isLoading = false) + currentState.copy(isSuccessfullyLogin = true, isLoading = false) } } } is Resource.Error -> { loginState.update { currentState -> - currentState.copy(errorMessageLoginProcess = result.message,isLoading = false) + currentState.copy( + errorMessageLoginProcess = result.message, + isLoading = false + ) } } } diff --git a/app/src/main/java/com/scholar/center/ui/auth/register/RegisterFragment.kt b/app/src/main/java/com/scholar/center/ui/auth/register/RegisterFragment.kt index 4900a56..f9cef90 100644 --- a/app/src/main/java/com/scholar/center/ui/auth/register/RegisterFragment.kt +++ b/app/src/main/java/com/scholar/center/ui/auth/register/RegisterFragment.kt @@ -1,6 +1,7 @@ package com.scholar.center.ui.auth.register import android.os.Bundle +import android.util.Log import android.view.View import android.view.animation.AlphaAnimation import androidx.core.widget.addTextChangedListener @@ -12,6 +13,7 @@ import androidx.lifecycle.repeatOnLifecycle import androidx.navigation.fragment.findNavController import com.scholar.center.R import com.scholar.center.databinding.FragmentRegisterBinding +import com.scholar.center.unit.Constants import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch @@ -24,7 +26,7 @@ class RegisterFragment : Fragment(R.layout.fragment_register) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { binding = FragmentRegisterBinding.bind(view) - + val mustPopBackStack = arguments?.getBoolean(Constants.MUST_POP_BACK_KEY) ?: false val navController = findNavController() @@ -33,7 +35,7 @@ class RegisterFragment : Fragment(R.layout.fragment_register) { } binding.registerFragmentLoginText.setOnClickListener { - navController.navigate(RegisterFragmentDirections.actionRegisterToLogin()) + navController.navigate(RegisterFragmentDirections.actionRegisterToLogin(mustPopBackStack)) } binding.registerFragmentFullNameEditText.addTextChangedListener { @@ -54,8 +56,15 @@ class RegisterFragment : Fragment(R.layout.fragment_register) { viewModel.registerState.collect { state -> val isLoginDestination = navController.currentDestination?.id == R.id.registerFragment //to ensure that navigate call once + Log.d("registerState", "isLoginDestination: $isLoginDestination") + Log.d("registerState", "state.isSuccessfullyRegister: ${state.isSuccessfullyRegister}") + Log.d("registerState", "mustPopBackStack: $mustPopBackStack") if (state.isSuccessfullyRegister && isLoginDestination) { - navController.navigate(RegisterFragmentDirections.actionRegisterToMain()) + if (mustPopBackStack) { + navController.popBackStack() + } else { + navController.navigate(RegisterFragmentDirections.actionRegisterToMain()) + } } binding.registerFragmentProgressBar.visibility = if (state.isLoading) View.VISIBLE else View.GONE @@ -64,13 +73,9 @@ class RegisterFragment : Fragment(R.layout.fragment_register) { state.errorMessageInput?.let { error -> binding.registerFragmentErrorText.text = getString(error) } - } } } - - - } private fun showTextError() { diff --git a/app/src/main/java/com/scholar/center/ui/auth/register/RegisterVM.kt b/app/src/main/java/com/scholar/center/ui/auth/register/RegisterVM.kt index 035187c..4e91aaa 100644 --- a/app/src/main/java/com/scholar/center/ui/auth/register/RegisterVM.kt +++ b/app/src/main/java/com/scholar/center/ui/auth/register/RegisterVM.kt @@ -7,6 +7,7 @@ import com.scholar.domain.model.RegisterInputValidationType import com.scholar.domain.model.RegisterState import com.scholar.domain.model.Resource import com.scholar.domain.repo.AuthRepository +import com.scholar.domain.repo.DataStorePreference import com.scholar.domain.usecase.ValidateRegisterUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow @@ -18,6 +19,7 @@ import javax.inject.Inject class RegisterVM @Inject constructor( private val validateRegisterUseCase: ValidateRegisterUseCase, private val authRepository: AuthRepository, + private val dataStore: DataStorePreference, ) : ViewModel() { var registerState = MutableStateFlow(RegisterState()) private set @@ -29,6 +31,7 @@ class RegisterVM @Inject constructor( } checkInputValidation() } + fun onEmailInputChanged(newValue: String) { registerState.update { currentState -> currentState.copy(emailInput = newValue) @@ -82,8 +85,9 @@ class RegisterVM @Inject constructor( ) when (result) { is Resource.Success -> { - result.data?.let { user -> -// dataStoreRepository.saveUser(user) + result.data?.let { studentID -> + dataStore.saveValue(DataStorePreference.userId, studentID) + dataStore.saveValue(DataStorePreference.isUserLoggedIn, true) registerState.update { currentState -> currentState.copy(isSuccessfullyRegister = true, isLoading = false) } diff --git a/app/src/main/java/com/scholar/center/ui/home/HomeFragment.kt b/app/src/main/java/com/scholar/center/ui/home/HomeFragment.kt index b175334..b15d438 100644 --- a/app/src/main/java/com/scholar/center/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/scholar/center/ui/home/HomeFragment.kt @@ -14,7 +14,7 @@ import com.scholar.center.adapter.CardClassITemAdapter import com.scholar.center.adapter.CategoryAdapter import com.scholar.center.adapter.MaterialAdapter import com.scholar.center.databinding.FragmentHomeBinding -import com.scholar.center.ui.MainFragmentDirections +import com.scholar.center.ui.main.MainFragmentDirections import com.scholar.domain.model.Stage import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/scholar/center/ui/MainFragment.kt b/app/src/main/java/com/scholar/center/ui/main/MainFragment.kt similarity index 65% rename from app/src/main/java/com/scholar/center/ui/MainFragment.kt rename to app/src/main/java/com/scholar/center/ui/main/MainFragment.kt index ccee1e5..24d50d5 100644 --- a/app/src/main/java/com/scholar/center/ui/MainFragment.kt +++ b/app/src/main/java/com/scholar/center/ui/main/MainFragment.kt @@ -1,28 +1,36 @@ -package com.scholar.center.ui +package com.scholar.center.ui.main import android.os.Bundle import android.view.LayoutInflater import androidx.fragment.app.Fragment import android.view.View import android.view.ViewGroup +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope import androidx.navigation.NavController import androidx.navigation.NavDestination import androidx.navigation.fragment.findNavController import androidx.navigation.ui.setupWithNavController import com.scholar.center.R import com.scholar.center.databinding.FragmentMainBinding +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.launch +@AndroidEntryPoint class MainFragment : Fragment(R.layout.fragment_main), NavController.OnDestinationChangedListener { private lateinit var binding: FragmentMainBinding + private val viewModel: MainVM by viewModels() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? + savedInstanceState: Bundle?, ): View { binding = FragmentMainBinding.inflate(inflater, container, false) - val nestedNavController = childFragmentManager.findFragmentById(R.id.main_nav_host_fragment)?.findNavController() + val nestedNavController = + childFragmentManager.findFragmentById(R.id.main_nav_host_fragment)?.findNavController() nestedNavController?.let { navController -> binding.mainNavBottom.setupWithNavController(navController) @@ -34,22 +42,26 @@ class MainFragment : Fragment(R.layout.fragment_main), NavController.OnDestinati } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - - } - override fun onDestinationChanged( controller: NavController, destination: NavDestination, arguments: Bundle?, ) { - if(destination.id != R.id.homeFragment){ + if (destination.id != R.id.homeFragment) { binding.mainStudentName.visibility = View.GONE - }else{ + } else { binding.mainStudentName.visibility = View.VISIBLE } } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + lifecycleScope.launch { + viewModel.studentName.collectLatest { name -> + binding.mainStudentName.text = getString(R.string.hi, name) + } + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/scholar/center/ui/main/MainVM.kt b/app/src/main/java/com/scholar/center/ui/main/MainVM.kt new file mode 100644 index 0000000..8cd3c73 --- /dev/null +++ b/app/src/main/java/com/scholar/center/ui/main/MainVM.kt @@ -0,0 +1,32 @@ +package com.scholar.center.ui.main + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.scholar.domain.repo.DataStorePreference +import com.scholar.domain.repo.StudentRepository +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class MainVM @Inject constructor( + private val studentRepository: StudentRepository, + private val dataStore: DataStorePreference, +) : ViewModel() { + + private val _studentName = MutableStateFlow(null) + val studentName = _studentName.asStateFlow() + + + init { + viewModelScope.launch { + val studentId = dataStore.readValue(DataStorePreference.userId).first() + studentId?.let { + _studentName.value = studentRepository.getStudentName(it) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/scholar/center/ui/setting/SettingsFragment.kt b/app/src/main/java/com/scholar/center/ui/setting/SettingsFragment.kt index ea878fc..173edde 100644 --- a/app/src/main/java/com/scholar/center/ui/setting/SettingsFragment.kt +++ b/app/src/main/java/com/scholar/center/ui/setting/SettingsFragment.kt @@ -6,16 +6,15 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.navigation.findNavController -import androidx.navigation.fragment.findNavController import com.scholar.center.R import com.scholar.center.databinding.FragmentProfileBinding -import com.scholar.center.ui.MainFragmentDirections +import com.scholar.center.ui.main.MainFragmentDirections class SettingsFragment : Fragment(R.layout.fragment_profile) { private lateinit var binding: FragmentProfileBinding - private val navController by lazy { activity?.findNavController(R.id.root_nav_host_fragment) } + private val navController by lazy { activity?.findNavController(R.id.root_nav_host_fragment) } override fun onCreateView( @@ -26,7 +25,7 @@ class SettingsFragment : Fragment(R.layout.fragment_profile) { binding = FragmentProfileBinding.inflate(inflater) val isUserLogin = true - if(isUserLogin){ + if (isUserLogin) { binding.profileFragmentStudentName.text = getString(R.string.guest) binding.profileFragmentAccountListTile.root.visibility = View.GONE binding.profileFragmentCashListTile.root.visibility = View.GONE @@ -34,9 +33,9 @@ class SettingsFragment : Fragment(R.layout.fragment_profile) { binding.profileWalletLayout.visibility = View.GONE binding.profileFragmentLogoutListTile.text.text = getString(R.string.login) binding.profileFragmentLogoutListTile.root.setOnClickListener { - navController?.navigate(MainFragmentDirections.actionMainToLogin()) + navController?.navigate(MainFragmentDirections.actionMainToLogin(mustPopBackStack = true)) } - }else{ + } else { binding.profileFragmentLogoutListTile.text.text = getString(R.string.logout) binding.profileFragmentLogoutListTile.root.setOnClickListener { } diff --git a/app/src/main/java/com/scholar/center/ui/stories/StoriesFragment.kt b/app/src/main/java/com/scholar/center/ui/stories/StoriesFragment.kt index 50b1841..ba51a68 100644 --- a/app/src/main/java/com/scholar/center/ui/stories/StoriesFragment.kt +++ b/app/src/main/java/com/scholar/center/ui/stories/StoriesFragment.kt @@ -11,7 +11,7 @@ import com.scholar.center.R import com.scholar.center.adapter.StoryAdapter import com.scholar.center.adapter.StoryComparator import com.scholar.center.databinding.FragmentStoriesBinding -import com.scholar.center.ui.MainFragmentDirections +import com.scholar.center.ui.main.MainFragmentDirections import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/scholar/center/ui/teachers/TeachersFragment.kt b/app/src/main/java/com/scholar/center/ui/teachers/TeachersFragment.kt index 6b77e89..66c8901 100644 --- a/app/src/main/java/com/scholar/center/ui/teachers/TeachersFragment.kt +++ b/app/src/main/java/com/scholar/center/ui/teachers/TeachersFragment.kt @@ -1,6 +1,5 @@ package com.scholar.center.ui.teachers -import android.R.attr.transitionName import android.os.Bundle import android.view.View import androidx.fragment.app.Fragment @@ -14,7 +13,7 @@ import com.scholar.center.R import com.scholar.center.adapter.TeacherComparator import com.scholar.center.adapter.TeacherProfileAdapter import com.scholar.center.databinding.FragmentTeachersBinding -import com.scholar.center.ui.MainFragmentDirections +import com.scholar.center.ui.main.MainFragmentDirections import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/scholar/center/unit/Constants.kt b/app/src/main/java/com/scholar/center/unit/Constants.kt index 6c4551a..23c6727 100644 --- a/app/src/main/java/com/scholar/center/unit/Constants.kt +++ b/app/src/main/java/com/scholar/center/unit/Constants.kt @@ -11,4 +11,5 @@ object Constants { const val SEARCH_FOCUS_KEY = "search_focus" const val CATEGORY_ID_KEY = "category_id" const val CLASSROOM_ID_KEY = "classroom_id" + const val MUST_POP_BACK_KEY = "mustPopBackStack" } \ No newline at end of file diff --git a/app/src/main/java/com/scholar/center/unit/ExtensionFun.kt b/app/src/main/java/com/scholar/center/unit/ExtensionFun.kt index 97c8ca2..4e22a4a 100644 --- a/app/src/main/java/com/scholar/center/unit/ExtensionFun.kt +++ b/app/src/main/java/com/scholar/center/unit/ExtensionFun.kt @@ -1,6 +1,8 @@ package com.scholar.center.unit import android.app.Activity +import android.content.Context +import android.util.TypedValue import android.view.View import android.view.inputmethod.InputMethodManager import androidx.appcompat.widget.SearchView @@ -14,4 +16,15 @@ fun View.closeKeyboard(activity: Activity?) { fun SearchView.openKeyboard(activity: Activity?) { val imm = activity?.getSystemService() imm?.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT) +} + + +fun Context.getThemeColor(resId: Int): Int { + val typedValue = TypedValue() + this.theme.resolveAttribute( + resId, + typedValue, + true + ) + return typedValue.data } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_login.xml b/app/src/main/res/layout/fragment_login.xml index 3ee4b38..b8b5d24 100644 --- a/app/src/main/res/layout/fragment_login.xml +++ b/app/src/main/res/layout/fragment_login.xml @@ -11,8 +11,8 @@ style="?android:attr/progressBarStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:visibility="gone" android:layout_marginTop="10dp" + android:visibility="gone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/loginFragment_login_btn" /> @@ -48,32 +48,16 @@ - - - - - - + app:layout_constraintTop_toTopOf="parent" /> @@ -124,11 +108,11 @@ android:id="@+id/loginFragment_error_text" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/TextBody2" - app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="10dp" - android:visibility="gone" + android:textAppearance="@style/TextBody2" android:textColor="?attr/colorError" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/loginFragment_password_editText" /> @@ -148,8 +132,6 @@ app:layout_constraintTop_toBottomOf="@+id/loginFragment_error_text" /> - - - + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent"> + android:textColor="?attr/colorPrimaryVariant" + android:textStyle="bold" /> - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml index 55efbcb..5d07a84 100644 --- a/app/src/main/res/layout/fragment_main.xml +++ b/app/src/main/res/layout/fragment_main.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" - tools:context=".ui.MainFragment"> + tools:context=".ui.main.MainFragment"> diff --git a/app/src/main/res/navigation/root_nav_graph.xml b/app/src/main/res/navigation/root_nav_graph.xml index 0c853d1..69977f1 100644 --- a/app/src/main/res/navigation/root_nav_graph.xml +++ b/app/src/main/res/navigation/root_nav_graph.xml @@ -3,12 +3,11 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/rout_nav_graph" - app:startDestination="@id/mainFragment" - > + app:startDestination="@id/mainFragment"> @@ -18,7 +17,7 @@ app:enterAnim="@anim/slide_in_right" app:exitAnim="@anim/slide_out_left" app:popEnterAnim="@anim/slide_in_left" - app:popExitAnim="@anim/slide_out_right" > + app:popExitAnim="@anim/slide_out_right"> + app:popExitAnim="@anim/fade_out_pop"> + app:popExitAnim="@anim/slide_out_right" /> + app:popExitAnim="@anim/slide_out_right"> + + @@ -110,7 +113,7 @@ android:id="@+id/materialsFragment" android:name="com.scholar.center.ui.materials.MaterialsFragment" android:label="fragment_subjects" - tools:layout="@layout/fragment_materials" > + tools:layout="@layout/fragment_materials"> + tools:layout="@layout/fragment_teacher"> + tools:layout="@layout/fragment_teachers_search"> + tools:layout="@layout/fragment_class_group"> + app:popUpToInclusive="true" + app:popUpToSaveState="true" > + + + app:popUpToSaveState="true" > + + هل انت أستاذ؟ تواصل معنا! الاسم الكامل + مرحبا %s + مرحبا بكم في تطبيق سكولار \ 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 c5c425a..4341364 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -107,4 +107,6 @@ Are you a teacher? Contact us! Full name + Hi %s + Welcome to the Scholar app \ No newline at end of file diff --git a/data/src/main/java/com/scholar/data/repo/AuthRepositoryImp.kt b/data/src/main/java/com/scholar/data/repo/AuthRepositoryImp.kt index bc25ada..edee953 100644 --- a/data/src/main/java/com/scholar/data/repo/AuthRepositoryImp.kt +++ b/data/src/main/java/com/scholar/data/repo/AuthRepositoryImp.kt @@ -1,6 +1,8 @@ package com.scholar.data.repo import com.scholar.data.service.ApiService +import com.scholar.data.source.local.dao.StudentDao +import com.scholar.data.source.local.model.toLocal import com.scholar.domain.model.NetworkResult import com.scholar.domain.model.Resource import com.scholar.domain.model.Student @@ -8,11 +10,14 @@ import com.scholar.domain.repo.AuthRepository class AuthRepositoryImp( private val apiService: ApiService, + private val studentDao: StudentDao, ) : AuthRepository { - override suspend fun login(email: String, password: String): Resource { + override suspend fun login(email: String, password: String): Resource { return when (val response = apiService.login(email, password)) { is NetworkResult.Success -> { - Resource.Success(response.data) + val student = response.data + studentDao.upsert(student.toLocal()) + Resource.Success(student.id) } is NetworkResult.Error -> { Resource.Error(response.error) @@ -27,10 +32,12 @@ class AuthRepositoryImp( fullName: String, email: String, password: String, - ): Resource { + ): Resource { return when (val response = apiService.register(fullName, email, password)) { is NetworkResult.Success -> { - Resource.Success(response.data) + val student = response.data + studentDao.upsert(student.toLocal()) + Resource.Success(student.id) } is NetworkResult.Error -> { Resource.Error(response.error) diff --git a/data/src/main/java/com/scholar/data/repo/StudentRepositoryImp.kt b/data/src/main/java/com/scholar/data/repo/StudentRepositoryImp.kt new file mode 100644 index 0000000..e270384 --- /dev/null +++ b/data/src/main/java/com/scholar/data/repo/StudentRepositoryImp.kt @@ -0,0 +1,14 @@ +package com.scholar.data.repo + +import com.scholar.data.source.local.dao.StudentDao +import com.scholar.domain.repo.StudentRepository + +class StudentRepositoryImp( + private val studentDao: StudentDao, +) :StudentRepository{ + override suspend fun getStudentName(id: Int): String? { + return studentDao.getStudentName(id) + } + + override fun getStudent(id: Int) = studentDao.getStudent(id) +} \ No newline at end of file diff --git a/data/src/main/java/com/scholar/data/source/local/dao/StudentDao.kt b/data/src/main/java/com/scholar/data/source/local/dao/StudentDao.kt index 8cd3c8f..801d7d2 100644 --- a/data/src/main/java/com/scholar/data/source/local/dao/StudentDao.kt +++ b/data/src/main/java/com/scholar/data/source/local/dao/StudentDao.kt @@ -1,9 +1,17 @@ package com.scholar.data.source.local.dao import androidx.room.Dao +import androidx.room.Query import com.scholar.data.source.local.model.StudentLocal +import kotlinx.coroutines.flow.Flow @Dao interface StudentDao : BaseDao { + + @Query("select fullName from students where id=:id") + suspend fun getStudentName(id: Int): String? + + @Query("select * from students where id=:id") + fun getStudent(id: Int): Flow } \ No newline at end of file diff --git a/data/src/main/java/com/scholar/di/DataModule.kt b/data/src/main/java/com/scholar/di/DataModule.kt index d0abe82..ae59095 100644 --- a/data/src/main/java/com/scholar/di/DataModule.kt +++ b/data/src/main/java/com/scholar/di/DataModule.kt @@ -135,8 +135,8 @@ object DataModule { @Singleton @Provides - fun provideAuthRepository(apiService: ApiService): AuthRepository { - return AuthRepositoryImp(apiService) + fun provideAuthRepository(apiService: ApiService, studentDao: StudentDao): AuthRepository { + return AuthRepositoryImp(apiService, studentDao) } @Singleton @@ -145,4 +145,9 @@ object DataModule { return DataStorePreferenceImp(context) } + @Singleton + @Provides + fun provideStudentRepository(studentDao: StudentDao): StudentRepository { + return StudentRepositoryImp(studentDao) + } } \ No newline at end of file diff --git a/domain/src/main/java/com/scholar/domain/repo/AuthRepository.kt b/domain/src/main/java/com/scholar/domain/repo/AuthRepository.kt index ff3b0c7..d34fb2b 100644 --- a/domain/src/main/java/com/scholar/domain/repo/AuthRepository.kt +++ b/domain/src/main/java/com/scholar/domain/repo/AuthRepository.kt @@ -5,12 +5,13 @@ import com.scholar.domain.model.Student interface AuthRepository { - suspend fun login(email: String, password: String): Resource + suspend fun login(email: String, password: String): Resource suspend fun register( fullName: String, email: String, password: String, - ): Resource + ): Resource suspend fun logout(): Resource + } \ No newline at end of file diff --git a/domain/src/main/java/com/scholar/domain/repo/DataStorePreference.kt b/domain/src/main/java/com/scholar/domain/repo/DataStorePreference.kt index af5c50e..8db752c 100644 --- a/domain/src/main/java/com/scholar/domain/repo/DataStorePreference.kt +++ b/domain/src/main/java/com/scholar/domain/repo/DataStorePreference.kt @@ -18,7 +18,7 @@ interface DataStorePreference { val isUserLoggedIn = booleanPreferencesKey(name = "is_user_logged_in") val isAppFirstOpen = booleanPreferencesKey(name = "app_first_open") val languageId = intPreferencesKey(name = "id_language") - val userId = stringPreferencesKey(name = "user_id") + val userId = intPreferencesKey(name = "user_id") } suspend fun saveValue(key: Preferences.Key, value: T) diff --git a/domain/src/main/java/com/scholar/domain/repo/StudentRepository.kt b/domain/src/main/java/com/scholar/domain/repo/StudentRepository.kt new file mode 100644 index 0000000..f2d7eb0 --- /dev/null +++ b/domain/src/main/java/com/scholar/domain/repo/StudentRepository.kt @@ -0,0 +1,11 @@ +package com.scholar.domain.repo + +import com.scholar.domain.model.Student +import kotlinx.coroutines.flow.Flow + + +interface StudentRepository { + + suspend fun getStudentName(id: Int): String? + fun getStudent(id: Int): Flow +} \ No newline at end of file