diff --git a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/main/MainActivity.kt b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/main/MainActivity.kt index 840a97ea..921f493e 100644 --- a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/main/MainActivity.kt +++ b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/main/MainActivity.kt @@ -11,7 +11,6 @@ import com.dongyang.android.youdongknowme.standard.base.BaseActivity import com.dongyang.android.youdongknowme.ui.view.util.KeepStateNavigator import com.google.firebase.messaging.FirebaseMessaging import org.koin.androidx.viewmodel.ext.android.viewModel -import timber.log.Timber /* 메인 액티비티 */ class MainActivity : BaseActivity() { @@ -46,11 +45,10 @@ class MainActivity : BaseActivity() { private fun getFcmToken() { viewModel.setIsFirstLaunch(false) FirebaseMessaging.getInstance().token.addOnCompleteListener { task -> + val token = task.result + if (task.isSuccessful) { - viewModel.setFCMToken(task.result).run { viewModel.setInitToken() } - Timber.d("token ${task.result}") - } else { - return@addOnCompleteListener + viewModel.setFCMToken(token).run { viewModel.setInitToken() } } } } @@ -61,4 +59,4 @@ class MainActivity : BaseActivity() { return Intent(context, MainActivity::class.java) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/setting/PermissionDialog.kt b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/setting/PermissionDialog.kt index dc0dc142..d3b07322 100644 --- a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/setting/PermissionDialog.kt +++ b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/setting/PermissionDialog.kt @@ -12,11 +12,20 @@ import android.view.ViewGroup import androidx.fragment.app.DialogFragment import com.dongyang.android.youdongknowme.databinding.DialogPermissionBinding -class PermissionDialog(val title: String, val content: String, val pacakageName: String) : DialogFragment() { +class PermissionDialog( + val title: String, + val content: String, + val pacakageName: String, + val cancelListener: (() -> Unit)? = null, +) : DialogFragment() { private var _binding: DialogPermissionBinding? = null private val binding get() = _binding!! - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View { _binding = DialogPermissionBinding.inflate(inflater, container, false) val view = binding.root @@ -29,8 +38,10 @@ class PermissionDialog(val title: String, val content: String, val pacakageName: // 취소 버튼 binding.customTvBtn1.setOnClickListener { + cancelListener?.invoke() dismiss() } + // 확인 버튼 binding.customTvBtn2.setOnClickListener { val intent = @@ -46,4 +57,4 @@ class PermissionDialog(val title: String, val content: String, val pacakageName: super.onDestroyView() _binding = null } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/setting/SettingFragment.kt b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/setting/SettingFragment.kt index db6cc300..06512fd8 100644 --- a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/setting/SettingFragment.kt +++ b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/setting/SettingFragment.kt @@ -1,17 +1,11 @@ package com.dongyang.android.youdongknowme.ui.view.setting -import android.app.Activity import android.Manifest import android.content.Intent import android.content.pm.PackageManager -import android.content.res.ColorStateList import android.net.Uri -import androidx.activity.result.ActivityResultLauncher -import androidx.activity.result.contract.ActivityResultContracts import android.os.Build -import android.view.View -import android.widget.Switch -import androidx.appcompat.widget.SwitchCompat +import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult import androidx.core.content.ContextCompat import com.dongyang.android.youdongknowme.R import com.dongyang.android.youdongknowme.databinding.FragmentSettingBinding @@ -27,29 +21,21 @@ class SettingFragment : BaseFragment() override val layoutResourceId: Int = R.layout.fragment_setting override val viewModel: SettingViewModel by viewModel() - private lateinit var resultLauncherKeyword: ActivityResultLauncher - private lateinit var resultResultDepartment: ActivityResultLauncher - - private var topics: List = emptyList() - private var department: String = "" + private val departmentActivityResultLauncher = + registerForActivityResult(StartActivityForResult()) { _ -> + // 학과 선택 화면 이동 후 재진입 시 학과 재조회 처리 + viewModel.getUserDepartment() + } override fun initStartView() { binding.tvSettingAppVersion.text = getAppVersion() - setResultKeyword() - setResultDepartment() + initAlarmSwitchStateByNotificationPermission() } override fun initDataBinding() { viewModel.myDepartment.observe(viewLifecycleOwner) { myDepartment -> binding.tvSettingDepartment.text = myDepartment - department = myDepartment - viewModel.updateUserDepartment(department) - } - - viewModel.myTopics.observe(viewLifecycleOwner) { myTopics -> - topics = myTopics - viewModel.updateUserTopic(topics) } viewModel.isAccessUniversityAlarm.observe(viewLifecycleOwner) { isChecked -> @@ -59,44 +45,60 @@ class SettingFragment : BaseFragment() viewModel.isAccessDepartAlarm.observe(viewLifecycleOwner) { isChecked -> binding.switchSettingDepartmentAlarm.isChecked = isChecked } + + viewModel.isLoading.observe(viewLifecycleOwner) { isLoading -> + if (isLoading) + showLoading() + else + dismissLoading() + } } override fun initAfterBinding() { + /** TODO 스위치 클릭을 억제하기 위한 임시 뷰, 후에 삭제 필요 */ + binding.viewSettingUniversityAlarm.setOnClickListener { + if (viewModel.isAccessUniversityAlarm.value == false) { + if (checkNotificationPermission().not()) { + showPermissionDialog() + return@setOnClickListener + } - viewModel.checkAccessAlarm() - viewModel.getUserDepartment() - viewModel.getUserTopic() + if (viewModel.myDepartment.value.isNullOrBlank()) + return@setOnClickListener - binding.switchSettingUniversityAlarm.setOnCheckedChangeListener { compoundButton, _ -> - checkPermission(binding.switchSettingUniversityAlarm) - if (compoundButton.isChecked) { - if (topics.isNotEmpty()) { - viewModel.updateUserTopic(topics) - } - } else { - viewModel.removeUserTopic() + viewModel.updateUserTopic() + return@setOnClickListener } + + viewModel.removeUserTopic() } - binding.switchSettingDepartmentAlarm.setOnCheckedChangeListener { compoundButton, _ -> - checkPermission(binding.switchSettingDepartmentAlarm) - if (compoundButton.isChecked) { - if (department.isNotEmpty()) { - viewModel.updateUserDepartment(department) + /** TODO 스위치 클릭을 억제하기 위한 임시 뷰, 후에 삭제 필요 */ + binding.viewSettingDepartmentAlarm.setOnClickListener { + if (viewModel.isAccessDepartAlarm.value == false) { + if (checkNotificationPermission().not()) { + showPermissionDialog() + return@setOnClickListener } - } else { - viewModel.removeUserDepartment() + + if (viewModel.myDepartment.value.isNullOrBlank()) + return@setOnClickListener + + viewModel.updateUserDepartment() + return@setOnClickListener } + + viewModel.removeUserDepartment() } binding.btnSettingEditKeyword.setOnClickListener { val intent = Intent(requireActivity(), KeywordActivity::class.java) - resultLauncherKeyword.launch(intent) + startActivity(intent) } binding.btnSettingEditDepartment.setOnClickListener { val intent = Intent(requireActivity(), DepartActivity::class.java) - resultResultDepartment.launch(intent) + departmentActivityResultLauncher.launch(intent) } binding.btnSettingAppHelp.setOnClickListener { @@ -121,51 +123,44 @@ class SettingFragment : BaseFragment() } } - private fun checkPermission(switch: SwitchCompat){ - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - if (PackageManager.PERMISSION_DENIED == ContextCompat.checkSelfPermission( - requireContext(), Manifest.permission.POST_NOTIFICATIONS - ) - ) { - // 알림 권한 설정 미허용 - viewModel.setIsAccessDepartAlarm(false) - viewModel.setIsAccessUniversityAlarm(false) - binding.switchSettingUniversityAlarm.isChecked = false - binding.switchSettingDepartmentAlarm.isChecked = false - - val dialog = PermissionDialog(getString(R.string.dialog_permission_title), getString(R.string.dialog_permission_content), requireContext().packageName) - dialog.show(parentFragmentManager, "CustomDialog") - } else { - switch.isChecked = !switch.isChecked - } - } else { - switch.isChecked = !switch.isChecked - } - } - private fun getAppVersion(): String { val packageManager = requireContext().packageManager.getPackageInfo(requireContext().packageName, 0) return packageManager.versionName } - private fun setResultKeyword() { - resultLauncherKeyword = - registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> - if (result.resultCode == Activity.RESULT_OK) { - viewModel.getUserTopic().run { viewModel.updateUserTopic(topics) } - binding.switchSettingUniversityAlarm.isChecked = true - } - } + private fun initAlarmSwitchStateByNotificationPermission() { + if (!checkNotificationPermission()) { + viewModel.setIsAccessDepartAlarm(false) + viewModel.setIsAccessUniversityAlarm(false) + } } - private fun setResultDepartment() { - resultResultDepartment = - registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> - if (result.resultCode == Activity.RESULT_OK) { - viewModel.getUserDepartment() - binding.switchSettingDepartmentAlarm.isChecked = true - } - } + private fun showPermissionDialog() { + val dialog = PermissionDialog( + title = getString(R.string.dialog_permission_title), + content = getString(R.string.dialog_permission_content), + pacakageName = requireContext().packageName, + cancelListener = { + viewModel.setIsAccessDepartAlarm(false) + viewModel.setIsAccessUniversityAlarm(false) + }) + + dialog.show(parentFragmentManager, null) + } + + private fun checkNotificationPermission(): Boolean { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) + return true + + if (PackageManager.PERMISSION_DENIED == ContextCompat.checkSelfPermission( + requireContext(), + Manifest.permission.POST_NOTIFICATIONS + ) + ) { + return false + } + + return true } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/setting/SettingViewModel.kt b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/setting/SettingViewModel.kt index 85779b9e..e78048cb 100644 --- a/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/setting/SettingViewModel.kt +++ b/app/src/main/java/com/dongyang/android/youdongknowme/ui/view/setting/SettingViewModel.kt @@ -24,10 +24,10 @@ class SettingViewModel(private val settingRepository: SettingRepository) : BaseV private val _isError: MutableLiveData = MutableLiveData() val isError: LiveData = _isError - private val _isAccessUniversityAlarm: MutableLiveData = MutableLiveData(false) + private val _isAccessUniversityAlarm: MutableLiveData = MutableLiveData() val isAccessUniversityAlarm: LiveData get() = _isAccessUniversityAlarm - private val _isAccessDepartAlarm: MutableLiveData = MutableLiveData(false) + private val _isAccessDepartAlarm: MutableLiveData = MutableLiveData() val isAccessDepartAlarm: LiveData get() = _isAccessDepartAlarm private val _myDepartment: MutableLiveData = MutableLiveData() @@ -36,35 +36,37 @@ class SettingViewModel(private val settingRepository: SettingRepository) : BaseV private val _myTopics: MutableLiveData> = MutableLiveData() val myTopics: LiveData> get() = _myTopics - private val _FCMToken: MutableLiveData = MutableLiveData() - val FCMToken: LiveData get() = _FCMToken + private var FCMToken: String = "" init { + checkAccessAlarm() getUserFCMToken() + getUserTopic() getUserDepartment() } fun checkAccessAlarm() { val isAccessUniversityAlarm = settingRepository.getIsAccessUniversityAlarm() _isAccessUniversityAlarm.postValue(isAccessUniversityAlarm) - val isAccessDepartAlarm = settingRepository.getIsAccessDepartAlarm() _isAccessDepartAlarm.postValue(isAccessDepartAlarm) } fun setIsAccessUniversityAlarm(isAccessSchoolAlarm: Boolean) { settingRepository.setIsAccessSchoolAlarm(isAccessSchoolAlarm) + checkAccessAlarm() } fun setIsAccessDepartAlarm(isAccessDepartAlarm: Boolean) { settingRepository.setIsAccessDepartAlarm(isAccessDepartAlarm) + checkAccessAlarm() } fun getUserDepartment() { _myDepartment.value = settingRepository.getUserDepartment() } - fun getUserTopic() { + private fun getUserTopic() { viewModelScope.launch { val keyword = settingRepository.getUserTopic() _myTopics.value = keyword @@ -72,27 +74,30 @@ class SettingViewModel(private val settingRepository: SettingRepository) : BaseV } private fun getUserFCMToken() { - _FCMToken.value = settingRepository.getUserFCMToken() + FCMToken = settingRepository.getUserFCMToken() } - fun updateUserDepartment(department: String) { + fun updateUserTopic() { _isLoading.postValue(true) viewModelScope.launch { - when (val result = settingRepository.updateUserDepartment( - UpdateDepartment( - token = FCMToken.value.toString(), - department = department + val result = settingRepository.updateUserTopic( + UpdateTopic( + token = FCMToken, + topics = myTopics.value ?: emptyList() ) - )) { + ) + + when (result) { is NetworkResult.Success -> { - setIsAccessDepartAlarm(true) + setIsAccessUniversityAlarm(true) _isLoading.postValue(false) _isError.postValue(false) } is NetworkResult.Error -> { handleError(result, _errorState) + setIsAccessUniversityAlarm(false) _isLoading.postValue(false) _isError.postValue(true) } @@ -100,23 +105,25 @@ class SettingViewModel(private val settingRepository: SettingRepository) : BaseV } } - fun removeUserDepartment() { + fun removeUserTopic() { _isLoading.postValue(true) viewModelScope.launch { - when (val result = - settingRepository.removeUserDepartment( - RemoveToken(token = FCMToken.value.toString()) + val result = + settingRepository.removeUserTopic( + RemoveToken(token = FCMToken) ) - ) { + + when (result) { is NetworkResult.Success -> { - setIsAccessDepartAlarm(false) + setIsAccessUniversityAlarm(false) _isLoading.postValue(false) _isError.postValue(false) } is NetworkResult.Error -> { handleError(result, _errorState) + setIsAccessUniversityAlarm(false) _isLoading.postValue(false) _isError.postValue(true) } @@ -124,24 +131,33 @@ class SettingViewModel(private val settingRepository: SettingRepository) : BaseV } } - fun updateUserTopic(topic: List) { + fun updateUserDepartment() { + val department = _myDepartment.value ?: run { + _isError.postValue(true) + setIsAccessDepartAlarm(false) + return + } + _isLoading.postValue(true) viewModelScope.launch { - when (val result = settingRepository.updateUserTopic( - UpdateTopic( - token = FCMToken.value.toString(), - topics = topic + val result = settingRepository.updateUserDepartment( + UpdateDepartment( + token = FCMToken, + department = department ) - )) { + ) + + when (result) { is NetworkResult.Success -> { - setIsAccessUniversityAlarm(true) + setIsAccessDepartAlarm(true) _isLoading.postValue(false) _isError.postValue(false) } is NetworkResult.Error -> { handleError(result, _errorState) + setIsAccessDepartAlarm(false) _isLoading.postValue(false) _isError.postValue(true) } @@ -149,26 +165,28 @@ class SettingViewModel(private val settingRepository: SettingRepository) : BaseV } } - fun removeUserTopic() { + fun removeUserDepartment() { _isLoading.postValue(true) viewModelScope.launch { - when (val result = - settingRepository.removeUserTopic( - RemoveToken(token = FCMToken.value.toString()) - )) { + val result = settingRepository.removeUserDepartment( + RemoveToken(token = FCMToken) + ) + + when (result) { is NetworkResult.Success -> { - setIsAccessUniversityAlarm(false) + setIsAccessDepartAlarm(false) _isLoading.postValue(false) _isError.postValue(false) } is NetworkResult.Error -> { handleError(result, _errorState) + setIsAccessDepartAlarm(false) _isLoading.postValue(false) _isError.postValue(true) } } } } -} \ No newline at end of file +} diff --git a/app/src/main/res/layout/activity_keyword.xml b/app/src/main/res/layout/activity_keyword.xml index 5416bb52..305fccb1 100644 --- a/app/src/main/res/layout/activity_keyword.xml +++ b/app/src/main/res/layout/activity_keyword.xml @@ -34,7 +34,8 @@ + android:layout_height="wrap_content" + android:paddingBottom="20dp"> - \ No newline at end of file + diff --git a/app/src/main/res/layout/fragment_cafeteria.xml b/app/src/main/res/layout/fragment_cafeteria.xml index 620669b6..5982cd6a 100644 --- a/app/src/main/res/layout/fragment_cafeteria.xml +++ b/app/src/main/res/layout/fragment_cafeteria.xml @@ -19,8 +19,8 @@ android:id="@+id/nsv_cafeteria_content" android:layout_width="0dp" android:layout_height="0dp" - android:fillViewport="true" android:layout_marginBottom="20dp" + android:fillViewport="true" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -147,6 +147,7 @@ android:layout_height="wrap_content" android:layout_marginVertical="8dp" android:layout_marginStart="8dp" + android:overScrollMode="never" tools:listitem="@layout/item_cafeteria_menu" /> @@ -187,6 +188,7 @@ android:layout_height="wrap_content" android:layout_marginVertical="8dp" android:layout_marginStart="8dp" + android:overScrollMode="never" tools:listitem="@layout/item_cafeteria_menu" /> diff --git a/app/src/main/res/layout/fragment_setting.xml b/app/src/main/res/layout/fragment_setting.xml index 32e29f7c..16c32c32 100644 --- a/app/src/main/res/layout/fragment_setting.xml +++ b/app/src/main/res/layout/fragment_setting.xml @@ -47,6 +47,8 @@ android:id="@+id/switch_setting_university_alarm" style="@style/PretendardMedium18" android:layout_width="0dp" + android:clickable="false" + android:focusable="false" android:layout_height="wrap_content" android:foreground="?attr/selectableItemBackground" android:minHeight="0dp" @@ -58,6 +60,17 @@ app:layout_constraintTop_toBottomOf="@id/tv_setting_university_title" tools:ignore="RtlSymmetry" /> + + + + - \ No newline at end of file +