diff --git a/app/src/main/java/com/popstack/mvoter2015/feature/about/AboutController.kt b/app/src/main/java/com/popstack/mvoter2015/feature/about/AboutController.kt index e9a0611..32c9a2c 100644 --- a/app/src/main/java/com/popstack/mvoter2015/feature/about/AboutController.kt +++ b/app/src/main/java/com/popstack/mvoter2015/feature/about/AboutController.kt @@ -2,10 +2,8 @@ package com.popstack.mvoter2015.feature.about import android.annotation.SuppressLint import android.content.Intent -import android.graphics.text.LineBreaker import android.net.Uri import android.os.Bundle -import android.text.Layout import android.view.LayoutInflater import androidx.lifecycle.lifecycleScope import com.bluelinelabs.conductor.RouterTransaction @@ -20,6 +18,7 @@ import com.popstack.mvoter2015.helper.conductor.requireActivity import com.popstack.mvoter2015.helper.conductor.requireContext import com.popstack.mvoter2015.helper.conductor.setSupportActionBar import com.popstack.mvoter2015.helper.conductor.supportActionBar +import com.popstack.mvoter2015.helper.extensions.justify import com.popstack.mvoter2015.logging.HasTag import kotlinx.coroutines.launch import javax.inject.Inject @@ -78,13 +77,7 @@ class AboutController : LifeCycleAwareController(), Inje openAppWebsite() } - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { - binding.tvCandidatePrivacyInstruction.justificationMode = LineBreaker.JUSTIFICATION_MODE_INTER_WORD - } else { - binding.tvCandidatePrivacyInstruction.justificationMode = Layout.JUSTIFICATION_MODE_INTER_WORD - } - } + binding.tvCandidatePrivacyInstruction.justify() binding.tvVersion.text = requireContext().getString(R.string.version, BuildConfig.VERSION_NAME) } diff --git a/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/CandidateListController.kt b/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/CandidateListController.kt index 338b480..a12199b 100644 --- a/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/CandidateListController.kt +++ b/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/CandidateListController.kt @@ -1,9 +1,7 @@ package com.popstack.mvoter2015.feature.candidate.listing import android.annotation.SuppressLint -import android.graphics.text.LineBreaker import android.os.Bundle -import android.text.Layout import android.view.LayoutInflater import android.view.View import androidx.core.view.isVisible @@ -20,10 +18,12 @@ import com.popstack.mvoter2015.feature.analytics.screen.ScreenTrackAnalyticsProv import com.popstack.mvoter2015.feature.candidate.search.CandidateSearchController import com.popstack.mvoter2015.feature.location.LocationUpdateController import com.popstack.mvoter2015.helper.ConstituencyTab +import com.popstack.mvoter2015.helper.asyncviewstate.AsyncViewState import com.popstack.mvoter2015.helper.conductor.requireActivity import com.popstack.mvoter2015.helper.conductor.requireContext import com.popstack.mvoter2015.helper.conductor.setSupportActionBar import com.popstack.mvoter2015.helper.conductor.supportActionBar +import com.popstack.mvoter2015.helper.extensions.justify import com.popstack.mvoter2015.logging.HasTag import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch @@ -57,8 +57,6 @@ class CandidateListController : selectedTab = savedViewState?.getInt(VIEW_STATE_SELECTED_TAB) - viewModel.viewEventLiveData.observe(this, Observer(::observeViewEvent)) - setSupportActionBar(binding.toolBar) supportActionBar()?.title = requireContext().getString(R.string.title_candidates) @@ -122,10 +120,38 @@ class CandidateListController : CandidateListPagerParentRouter.setParentRouter(router) - showCandidatePrivacyInstructionIfNeeded() + viewModel.houseViewItemListResultLiveData.observe(this, Observer(::observeHouseViewItemListResult)) + + if (viewModel.houseViewItemListResultLiveData.value == null) { + viewModel.loadHouses() + } + } - viewModel.houseViewItemListLiveData.observe(lifecycleOwner, Observer(::observeHouseViewItem)) - viewModel.loadHouses() + private fun observeHouseViewItemListResult(viewState: AsyncViewState) { + if (viewState is AsyncViewState.Loading) binding.progressIndicator.show() + else binding.progressIndicator.hide() + + if (viewState is AsyncViewState.Success) { + val result = viewState.value + binding.tabLayout.isVisible = result is CandidateListViewModel.HouseViewItemListResult.HouseViewItemList + binding.viewPager.isVisible = result is CandidateListViewModel.HouseViewItemListResult.HouseViewItemList + binding.groupChooseCandidateComponent.isVisible = result is CandidateListViewModel.HouseViewItemListResult.RequestUserLocation + if (result is CandidateListViewModel.HouseViewItemListResult.HouseViewItemList) { + showCandidatePrivacyInstructionIfNeeded() + pagerAdapter.setItems(result.itemList) + binding.tabLayout.removeAllTabs() + result.itemList.forEach { + binding.tabLayout.addTab( + binding.tabLayout.newTab().setCustomView( + ConstituencyTab(requireActivity()).apply { + setText(it.houseName) + } + ) + ) + } + changeSelectedTabIfNeeded() + } + } } @Inject @@ -133,13 +159,7 @@ class CandidateListController : @SuppressLint("WrongConstant") private fun showCandidatePrivacyInstructionIfNeeded() { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { - binding.tvCandidatePrivacyInstruction.justificationMode = LineBreaker.JUSTIFICATION_MODE_INTER_WORD - } else { - binding.tvCandidatePrivacyInstruction.justificationMode = Layout.JUSTIFICATION_MODE_INTER_WORD - } - } + binding.tvCandidatePrivacyInstruction.justify() lifecycleScope.launch { viewCache.shouldShowCandidatePrivacyInstruction().collectLatest { @@ -178,29 +198,6 @@ class CandidateListController : binding.viewPager.isVisible = false } - private fun observeViewEvent(viewEvent: CandidateListViewModel.ViewEvent) { - if (viewEvent is CandidateListViewModel.ViewEvent.RequestUserLocation) { - binding.tabLayout.isVisible = false - binding.groupChooseCandidateComponent.isVisible = true - } - } - - private fun observeHouseViewItem(houseViewItemList: List) { - binding.groupChooseCandidateComponent.isVisible = false - pagerAdapter.setItems(houseViewItemList) - binding.tabLayout.removeAllTabs() - houseViewItemList.forEach { - binding.tabLayout.addTab( - binding.tabLayout.newTab().setCustomView( - ConstituencyTab(requireActivity()).apply { - setText(it.houseName) - } - ) - ) - } - changeSelectedTabIfNeeded() - } - private fun changeSelectedTabIfNeeded() { selectedTab?.let { binding.viewPager.post { diff --git a/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/CandidateListViewModel.kt b/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/CandidateListViewModel.kt index 1942fd2..ca9c053 100644 --- a/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/CandidateListViewModel.kt +++ b/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/CandidateListViewModel.kt @@ -3,39 +3,49 @@ package com.popstack.mvoter2015.feature.candidate.listing import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.popstack.mvoter2015.domain.constituency.model.HouseType -import com.popstack.mvoter2015.domain.location.usecase.GetUserStateRegion import com.popstack.mvoter2015.domain.location.usecase.GetUserWard -import com.popstack.mvoter2015.helper.livedata.SingleLiveEvent +import com.popstack.mvoter2015.domain.location.usecase.UpdateWardDetails +import com.popstack.mvoter2015.helper.asyncviewstate.AsyncViewStateLiveData import kotlinx.coroutines.launch import javax.inject.Inject class CandidateListViewModel @Inject constructor( private val houseViewItemMapper: CandidateListHouseViewItemMapper, - private val getUserStateRegion: GetUserStateRegion, + private val updateWardDetails: UpdateWardDetails, private val getUserWard: GetUserWard ) : ViewModel() { - sealed class ViewEvent { - object RequestUserLocation : ViewEvent() - } + sealed class HouseViewItemListResult { + object RequestUserLocation : HouseViewItemListResult() - val viewEventLiveData = SingleLiveEvent() + data class HouseViewItemList( + val itemList: List + ) : HouseViewItemListResult() + } - val houseViewItemListLiveData = - SingleLiveEvent>() + val houseViewItemListResultLiveData = + AsyncViewStateLiveData() fun loadHouses() { viewModelScope.launch { - val houseTypes = HouseType.values() - val userWard = getUserWard.execute(Unit) ?: run { - viewEventLiveData.postValue(ViewEvent.RequestUserLocation) + houseViewItemListResultLiveData.postSuccess(HouseViewItemListResult.RequestUserLocation) return@launch } - val viewItems = houseTypes.map { houseType -> - houseViewItemMapper.mapFromHouseType(houseType, userWard) + + houseViewItemListResultLiveData.postLoading() + + try { + updateWardDetails.execute(Unit) + } catch (exception: Exception) { + //Ignore exception, allow update to fail + } finally { + val houseTypes = HouseType.values() + val viewItems = houseTypes.map { houseType -> + houseViewItemMapper.mapFromHouseType(houseType, userWard) + } + houseViewItemListResultLiveData.postSuccess(HouseViewItemListResult.HouseViewItemList(viewItems)) } - houseViewItemListLiveData.postValue(viewItems) } } } \ No newline at end of file diff --git a/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/lowerhouse/LowerHouseCandidateListController.kt b/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/lowerhouse/LowerHouseCandidateListController.kt index cec37b6..56a89ad 100644 --- a/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/lowerhouse/LowerHouseCandidateListController.kt +++ b/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/lowerhouse/LowerHouseCandidateListController.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.LayoutInflater import androidx.core.view.isVisible import androidx.lifecycle.Observer +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import com.bluelinelabs.conductor.RouterTransaction @@ -21,6 +22,8 @@ import com.popstack.mvoter2015.helper.conductor.requireContext import com.popstack.mvoter2015.helper.extensions.isLandScape import com.popstack.mvoter2015.helper.extensions.isTablet import com.popstack.mvoter2015.logging.HasTag +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch class LowerHouseCandidateListController : MvvmController(), HasTag { @@ -65,7 +68,7 @@ class LowerHouseCandidateListController : MvvmController) = with(binding) { progressBar.isVisible = viewState is AsyncViewState.Loading - rvCandidate.isVisible = viewState is AsyncViewState.Success tvErrorMessage.isVisible = viewState is AsyncViewState.Error btnRetry.isVisible = viewState is AsyncViewState.Error diff --git a/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/regionalhouse/RegionalHouseCandidateListController.kt b/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/regionalhouse/RegionalHouseCandidateListController.kt index 50e36ed..f06d6e7 100644 --- a/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/regionalhouse/RegionalHouseCandidateListController.kt +++ b/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/regionalhouse/RegionalHouseCandidateListController.kt @@ -85,7 +85,6 @@ class RegionalHouseCandidateListController() : MvvmController) = with(binding) { progressBar.isVisible = viewState is AsyncViewState.Loading - rvCandidate.isVisible = viewState is AsyncViewState.Success tvErrorMessage.isVisible = viewState is AsyncViewState.Error btnRetry.isVisible = viewState is AsyncViewState.Error groupRemark.isVisible = false diff --git a/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/upperhouse/UpperHouseCandidateListController.kt b/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/upperhouse/UpperHouseCandidateListController.kt index 86cb68a..77a363b 100644 --- a/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/upperhouse/UpperHouseCandidateListController.kt +++ b/app/src/main/java/com/popstack/mvoter2015/feature/candidate/listing/upperhouse/UpperHouseCandidateListController.kt @@ -82,7 +82,6 @@ class UpperHouseCandidateListController : MvvmController) = with(binding) { progressBar.isVisible = viewState is AsyncViewState.Loading - rvCandidate.isVisible = viewState is AsyncViewState.Success tvErrorMessage.isVisible = viewState is AsyncViewState.Error btnRetry.isVisible = viewState is AsyncViewState.Error diff --git a/app/src/main/java/com/popstack/mvoter2015/helper/extensions/TextViewExtensions.kt b/app/src/main/java/com/popstack/mvoter2015/helper/extensions/TextViewExtensions.kt index 4a34f31..4c03550 100644 --- a/app/src/main/java/com/popstack/mvoter2015/helper/extensions/TextViewExtensions.kt +++ b/app/src/main/java/com/popstack/mvoter2015/helper/extensions/TextViewExtensions.kt @@ -1,6 +1,8 @@ package com.popstack.mvoter2015.helper.extensions +import android.annotation.SuppressLint import android.graphics.drawable.Drawable +import android.text.Layout import android.widget.TextView fun TextView.setCompoundDrawablesKt( @@ -19,4 +21,11 @@ fun TextView.setCompoundDrawableWithIntrinsicBoundsKt( bottom: Drawable? = null ) { this.setCompoundDrawablesRelativeWithIntrinsicBounds(start, top, end, bottom) +} + +@SuppressLint("WrongConstant") +fun TextView.justify() { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + justificationMode = Layout.JUSTIFICATION_MODE_INTER_WORD + } } \ No newline at end of file diff --git a/app/src/main/res/layout/controller_candidate_list.xml b/app/src/main/res/layout/controller_candidate_list.xml index bb45443..7aa2e6a 100644 --- a/app/src/main/res/layout/controller_candidate_list.xml +++ b/app/src/main/res/layout/controller_candidate_list.xml @@ -1,9 +1,9 @@ + + + android:visibility="gone" + app:cardBackgroundColor="@color/accent" + tools:visibility="visible"> - \ No newline at end of file diff --git a/app/src/main/res/layout/controller_lower_house_candidate_list.xml b/app/src/main/res/layout/controller_lower_house_candidate_list.xml index 563274d..aabc1ef 100644 --- a/app/src/main/res/layout/controller_lower_house_candidate_list.xml +++ b/app/src/main/res/layout/controller_lower_house_candidate_list.xml @@ -33,6 +33,7 @@ android:layout_height="0dp" android:layout_marginTop="8dp" app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvConstituencyName" /> diff --git a/app/src/main/res/layout/controller_regional_candidate_list.xml b/app/src/main/res/layout/controller_regional_candidate_list.xml index e1212ff..5e84884 100644 --- a/app/src/main/res/layout/controller_regional_candidate_list.xml +++ b/app/src/main/res/layout/controller_regional_candidate_list.xml @@ -11,6 +11,7 @@ android:layout_height="0dp" android:clipToPadding="false" app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> diff --git a/app/src/main/res/layout/controller_upper_house_candidate_list.xml b/app/src/main/res/layout/controller_upper_house_candidate_list.xml index a714d1a..1db5ab1 100644 --- a/app/src/main/res/layout/controller_upper_house_candidate_list.xml +++ b/app/src/main/res/layout/controller_upper_house_candidate_list.xml @@ -33,6 +33,7 @@ android:layout_height="0dp" android:layout_marginTop="8dp" app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvConstituencyName" /> diff --git a/app/src/main/res/layout/item_party_header.xml b/app/src/main/res/layout/item_party_header.xml index 4e2d159..4ec4a4d 100644 --- a/app/src/main/res/layout/item_party_header.xml +++ b/app/src/main/res/layout/item_party_header.xml @@ -23,7 +23,7 @@ android:layout_height="12dp" android:layout_gravity="center" android:src="@drawable/ic_flag_24" - app:tint="@color/accent_20" /> + app:tint="@android:color/white" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1bcc68c..6f8ce10 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -60,7 +60,7 @@ အနိုင်ရ - (၂၀၂၀) ပြည့်နှစ် အထွေထွေရွေးကောက်ပွဲတွင် ဝင်ရောက်ယှဉ်ပြိုင်မည့် နိုင်ငံရေးပါတီ (၉၂) ခု + (၂၀၂၀) ပြည့်နှစ် အထွေထွေရွေးကောက်ပွဲတွင် ဝင်ရောက်ယှဉ်ပြိုင်မည့် နိုင်ငံရေးပါတီ (၉၁) ခု ပါတီ မူဝါဒ ပါတီအလံ diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index 6fd4404..24347e7 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -5,7 +5,7 @@ object BuildConfig { private const val versionMajor = 4 private const val versionMinor = 1 - private const val versionPatch = 2 + private const val versionPatch = 5 private const val versionBuild = 0 const val versionName = @@ -86,7 +86,7 @@ object AndroidXPaging { //endregion object Material { - const val material = "com.google.android.material:material:1.3.0-alpha02" + const val material = "com.google.android.material:material:1.3.0-alpha03" } object Coil { diff --git a/domain/src/main/java/com/popstack/mvoter2015/domain/location/usecase/UpdateWardDetails.kt b/domain/src/main/java/com/popstack/mvoter2015/domain/location/usecase/UpdateWardDetails.kt new file mode 100644 index 0000000..e5ef8d2 --- /dev/null +++ b/domain/src/main/java/com/popstack/mvoter2015/domain/location/usecase/UpdateWardDetails.kt @@ -0,0 +1,26 @@ +package com.popstack.mvoter2015.domain.location.usecase + +import com.popstack.mvoter2015.domain.CoroutineUseCase +import com.popstack.mvoter2015.domain.DispatcherProvider +import com.popstack.mvoter2015.domain.location.LocationRepository +import javax.inject.Inject + +class UpdateWardDetails @Inject constructor( + dispatcherProvider: DispatcherProvider, + private val locationRepository: LocationRepository +) : CoroutineUseCase(dispatcherProvider) { + + override suspend fun provide(input: Unit) { + val stateRegionTownship = locationRepository.getUserStateRegionTownship() ?: return + val ward = locationRepository.getUserWard() ?: return + + val updatedWard = locationRepository.getWardDetails( + stateRegionTownship.stateRegion, + stateRegionTownship.township, + ward.name + ) + + locationRepository.saveUserWard(updatedWard) + } + +} \ No newline at end of file