A fork of Simple Time Tracker with WearOS support. (Now integrated upstream)
0

Configure Feed

Select the types of activity you want to include in your feed.

change icons search state switching

razeeman (Feb 10, 2024, 7:58 PM +0300) 3a59fcc1 6b1508c0

+89 -63
+6
domain/src/main/java/com/example/util/simpletimetracker/domain/model/IconImageState.kt
··· 1 + package com.example.util.simpletimetracker.domain.model 2 + 3 + sealed interface IconImageState { 4 + object Chooser : IconImageState 5 + object Search : IconImageState 6 + }
+1 -1
features/feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/interactor/ChangeRecordTypeViewDataInteractor.kt
··· 6 6 import com.example.util.simpletimetracker.domain.interactor.PrefsInteractor 7 7 import com.example.util.simpletimetracker.domain.model.AppColor 8 8 import com.example.util.simpletimetracker.domain.model.Category 9 + import com.example.util.simpletimetracker.domain.model.IconImageState 9 10 import com.example.util.simpletimetracker.domain.model.IconType 10 11 import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType 11 12 import com.example.util.simpletimetracker.feature_base_adapter.divider.DividerViewData 12 13 import com.example.util.simpletimetracker.feature_change_record_type.mapper.ChangeRecordTypeMapper 13 - import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconImageStateViewData.IconImageState 14 14 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconStateViewData 15 15 import kotlinx.coroutines.Dispatchers 16 16 import kotlinx.coroutines.withContext
+17 -14
features/feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/mapper/ChangeRecordTypeMapper.kt
··· 5 5 import com.example.util.simpletimetracker.core.mapper.IconImageMapper 6 6 import com.example.util.simpletimetracker.core.repo.ResourceRepo 7 7 import com.example.util.simpletimetracker.domain.model.AppColor 8 + import com.example.util.simpletimetracker.domain.model.IconImageState 8 9 import com.example.util.simpletimetracker.domain.model.IconType 9 10 import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType 10 11 import com.example.util.simpletimetracker.feature_base_adapter.emoji.EmojiViewData 11 12 import com.example.util.simpletimetracker.feature_change_record_type.R 12 13 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconCategoryInfoViewData 13 14 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconCategoryViewData 14 - import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconImageStateViewData 15 - import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconImageStateViewData.IconImageState 15 + import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconSelectorStateViewData 16 16 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconSwitchViewData 17 17 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconTypeViewData 18 18 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconViewData ··· 122 122 } 123 123 } 124 124 125 - fun mapToIconImageStateViewData( 125 + fun mapToIconSelectorViewData( 126 126 iconImageState: IconImageState, 127 127 iconType: IconType, 128 128 isDarkTheme: Boolean, 129 - ): ChangeRecordTypeIconImageStateViewData { 130 - val theme = if (isDarkTheme) R.style.AppThemeDark else R.style.AppTheme 131 - 132 - return ChangeRecordTypeIconImageStateViewData( 133 - state = if (iconType != IconType.IMAGE) IconImageState.Chooser else iconImageState, 134 - searchButtonIsVisible = iconType == IconType.IMAGE, 135 - searchButtonColor = when (iconImageState) { 136 - is IconImageState.Chooser -> R.attr.appInactiveColor 137 - is IconImageState.Search -> R.attr.colorSecondary 138 - }.let { resourceRepo.getThemedAttr(it, theme) }, 139 - ) 129 + ): ChangeRecordTypeIconSelectorStateViewData { 130 + return if (iconType == IconType.TEXT) { 131 + ChangeRecordTypeIconSelectorStateViewData.None 132 + } else { 133 + val theme = if (isDarkTheme) R.style.AppThemeDark else R.style.AppTheme 134 + ChangeRecordTypeIconSelectorStateViewData.Available( 135 + state = if (iconType != IconType.IMAGE) IconImageState.Chooser else iconImageState, 136 + searchButtonIsVisible = iconType == IconType.IMAGE, 137 + searchButtonColor = when (iconImageState) { 138 + is IconImageState.Chooser -> R.attr.appInactiveColor 139 + is IconImageState.Search -> R.attr.colorSecondary 140 + }.let { resourceRepo.getThemedAttr(it, theme) }, 141 + ) 142 + } 140 143 } 141 144 142 145 fun mapEmojiSelectionParams(
+27 -15
features/feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/view/ChangeRecordTypeFragment.kt
··· 22 22 import com.example.util.simpletimetracker.core.utils.fragmentArgumentDelegate 23 23 import com.example.util.simpletimetracker.core.view.buttonsRowView.ButtonsRowViewData 24 24 import com.example.util.simpletimetracker.domain.model.IconEmojiType 25 + import com.example.util.simpletimetracker.domain.model.IconImageState 25 26 import com.example.util.simpletimetracker.domain.model.IconType 26 27 import com.example.util.simpletimetracker.feature_base_adapter.BaseRecyclerAdapter 27 28 import com.example.util.simpletimetracker.feature_base_adapter.category.createCategoryAdapterDelegate ··· 35 36 import com.example.util.simpletimetracker.feature_base_adapter.hint.createHintAdapterDelegate 36 37 import com.example.util.simpletimetracker.feature_base_adapter.hintBig.createHintBigAdapterDelegate 37 38 import com.example.util.simpletimetracker.feature_base_adapter.info.createInfoAdapterDelegate 39 + import com.example.util.simpletimetracker.feature_base_adapter.loader.LoaderViewData 40 + import com.example.util.simpletimetracker.feature_base_adapter.loader.createLoaderAdapterDelegate 38 41 import com.example.util.simpletimetracker.feature_base_adapter.recordType.RecordTypeViewData 39 42 import com.example.util.simpletimetracker.feature_change_record_type.R 40 43 import com.example.util.simpletimetracker.feature_change_record_type.adapter.createChangeRecordTypeIconAdapterDelegate ··· 49 52 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeChooserState.State.Icon 50 53 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeGoalsViewData 51 54 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconCategoryInfoViewData 52 - import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconImageStateViewData 53 - import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconImageStateViewData.IconImageState 55 + import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconSelectorStateViewData 54 56 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconStateViewData 55 57 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconSwitchViewData 56 58 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeScrollViewData ··· 96 98 } 97 99 private val iconsAdapter: BaseRecyclerAdapter by lazy { 98 100 BaseRecyclerAdapter( 101 + createLoaderAdapterDelegate(), 99 102 createChangeRecordTypeIconAdapterDelegate(viewModel::onIconClick), 100 103 createEmojiAdapterDelegate(viewModel::onEmojiClick), 101 104 createChangeRecordTypeIconCategoryInfoAdapterDelegate(), ··· 158 161 layoutManager = GridLayoutManager(requireContext(), getIconsColumnCount()) 159 162 .also { iconsLayoutManager = it } 160 163 adapter = iconsAdapter 164 + itemAnimator = null 161 165 setIconsSpanSize() 162 166 } 163 167 164 168 rvChangeRecordTypeIconCategory.apply { 165 169 layoutManager = GridLayoutManager(requireContext(), IconEmojiType.values().size) 166 170 adapter = iconCategoriesAdapter 171 + itemAnimator = null 167 172 } 168 173 169 174 rvChangeRecordTypeCategories.apply { ··· 225 230 recordType.observe(::updatePreview) 226 231 colors.observe(colorsAdapter::replace) 227 232 icons.observe(::updateIconsState) 228 - iconCategories.observe(iconCategoriesAdapter::replace) 233 + iconCategories.observe(iconCategoriesAdapter::replaceAsNew) 229 234 iconsTypeViewData.observe(btnChangeRecordTypeIconSwitch.adapter::replace) 230 - iconImageStateViewData.observe(::updateIconImageStateViewData) 235 + iconSelectorViewData.observe(::updateIconSelectorViewData) 231 236 categories.observe(categoriesAdapter::replace) 232 237 goalsViewData.observe(::updateGoalsState) 233 238 notificationsHintVisible.observe( ··· 357 362 is ChangeRecordTypeIconStateViewData.Icons -> { 358 363 rvChangeRecordTypeIcon.isVisible = true 359 364 inputChangeRecordTypeIconText.isVisible = false 360 - iconsAdapter.replace(state.items) 365 + iconsAdapter.replaceAsNew(state.items) 361 366 } 362 367 is ChangeRecordTypeIconStateViewData.Text -> { 363 368 rvChangeRecordTypeIcon.isVisible = false ··· 384 389 385 390 private fun setIconsSpanSize() { 386 391 iconsLayoutManager?.setSpanSizeLookup { position -> 387 - if (iconsAdapter.getItemByPosition(position) is ChangeRecordTypeIconCategoryInfoViewData) { 388 - iconsLayoutManager?.spanCount ?: 1 389 - } else { 390 - 1 392 + when (iconsAdapter.getItemByPosition(position)) { 393 + is ChangeRecordTypeIconCategoryInfoViewData, 394 + is LoaderViewData, 395 + -> iconsLayoutManager?.spanCount ?: 1 396 + else -> 1 391 397 } 392 398 } 393 399 } ··· 402 408 ?.scrollFlags = scrollFlags 403 409 } 404 410 405 - private fun updateIconImageStateViewData( 406 - data: ChangeRecordTypeIconImageStateViewData, 411 + private fun updateIconSelectorViewData( 412 + data: ChangeRecordTypeIconSelectorStateViewData, 407 413 ) = with(binding) { 408 - btnChangeRecordTypeIconSearch.isVisible = data.searchButtonIsVisible 409 - ivChangeRecordTypeIconSearch.backgroundTintList = ColorStateList.valueOf(data.searchButtonColor) 410 - rvChangeRecordTypeIconCategory.isVisible = data.state is IconImageState.Chooser 411 - inputChangeRecordTypeIconSearch.isVisible = data.state is IconImageState.Search 414 + if (data is ChangeRecordTypeIconSelectorStateViewData.Available) { 415 + btnChangeRecordTypeIconSearch.isVisible = data.searchButtonIsVisible 416 + ivChangeRecordTypeIconSearch.backgroundTintList = ColorStateList.valueOf(data.searchButtonColor) 417 + rvChangeRecordTypeIconCategory.isVisible = data.state is IconImageState.Chooser 418 + inputChangeRecordTypeIconSearch.isVisible = data.state is IconImageState.Search 419 + } else { 420 + btnChangeRecordTypeIconSearch.isVisible = false 421 + rvChangeRecordTypeIconCategory.isVisible = false 422 + inputChangeRecordTypeIconSearch.isVisible = false 423 + } 412 424 } 413 425 414 426 companion object {
-15
features/feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/viewData/ChangeRecordTypeIconImageStateViewData.kt
··· 1 - package com.example.util.simpletimetracker.feature_change_record_type.viewData 2 - 3 - import androidx.annotation.ColorInt 4 - 5 - data class ChangeRecordTypeIconImageStateViewData( 6 - val state: IconImageState, 7 - val searchButtonIsVisible: Boolean, 8 - @ColorInt val searchButtonColor: Int, 9 - ) { 10 - 11 - sealed interface IconImageState { 12 - object Chooser : IconImageState 13 - object Search : IconImageState 14 - } 15 - }
+15
features/feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/viewData/ChangeRecordTypeIconSelectorStateViewData.kt
··· 1 + package com.example.util.simpletimetracker.feature_change_record_type.viewData 2 + 3 + import androidx.annotation.ColorInt 4 + import com.example.util.simpletimetracker.domain.model.IconImageState 5 + 6 + sealed interface ChangeRecordTypeIconSelectorStateViewData { 7 + 8 + data class Available( 9 + val state: IconImageState, 10 + val searchButtonIsVisible: Boolean, 11 + @ColorInt val searchButtonColor: Int, 12 + ) : ChangeRecordTypeIconSelectorStateViewData 13 + 14 + object None : ChangeRecordTypeIconSelectorStateViewData 15 + }
+23 -18
features/feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/viewModel/ChangeRecordTypeViewModel.kt
··· 22 22 import com.example.util.simpletimetracker.domain.interactor.RunningRecordInteractor 23 23 import com.example.util.simpletimetracker.domain.interactor.WidgetInteractor 24 24 import com.example.util.simpletimetracker.domain.model.AppColor 25 + import com.example.util.simpletimetracker.domain.model.IconImageState 25 26 import com.example.util.simpletimetracker.domain.model.IconType 26 27 import com.example.util.simpletimetracker.domain.model.RecordType 27 28 import com.example.util.simpletimetracker.domain.model.RecordTypeGoal ··· 29 30 import com.example.util.simpletimetracker.feature_base_adapter.category.CategoryViewData 30 31 import com.example.util.simpletimetracker.feature_base_adapter.color.ColorViewData 31 32 import com.example.util.simpletimetracker.feature_base_adapter.emoji.EmojiViewData 33 + import com.example.util.simpletimetracker.feature_base_adapter.loader.LoaderViewData 32 34 import com.example.util.simpletimetracker.feature_base_adapter.recordType.RecordTypeViewData 33 35 import com.example.util.simpletimetracker.feature_change_record_type.R 34 36 import com.example.util.simpletimetracker.feature_change_record_type.goals.GoalsViewModelDelegate ··· 38 40 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeChooserState 39 41 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconCategoryInfoViewData 40 42 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconCategoryViewData 41 - import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconImageStateViewData 42 - import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconImageStateViewData.IconImageState 43 + import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconSelectorStateViewData 43 44 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconStateViewData 44 45 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconSwitchViewData 45 46 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconViewData ··· 109 110 val iconsTypeViewData: LiveData<List<ViewHolderType>> by lazy { 110 111 return@lazy MutableLiveData(loadIconsTypeViewData()) 111 112 } 112 - val iconImageStateViewData: LiveData<ChangeRecordTypeIconImageStateViewData> by lazy { 113 - return@lazy MutableLiveData<ChangeRecordTypeIconImageStateViewData>().let { initial -> 114 - viewModelScope.launch { initial.value = loadIconImageStateViewData() } 113 + val iconSelectorViewData: LiveData<ChangeRecordTypeIconSelectorStateViewData> by lazy { 114 + return@lazy MutableLiveData<ChangeRecordTypeIconSelectorStateViewData>().let { initial -> 115 + viewModelScope.launch { initial.value = loadIconSelectorViewData() } 115 116 initial 116 117 } 117 118 } ··· 221 222 if (viewData !is ChangeRecordTypeIconSwitchViewData) return 222 223 if (viewData.iconType == iconType) return 223 224 viewModelScope.launch { 224 - if (viewData.iconType != IconType.TEXT) { 225 - keyboardVisibility.set(false) 226 - icons.set(ChangeRecordTypeIconStateViewData.Icons(emptyList())) 227 - } 225 + keyboardVisibility.set(false) 228 226 iconType = viewData.iconType 229 227 updateIconsTypeViewData() 228 + updateIconSelectorViewData() 230 229 updateIconCategories(selectedIndex = 0) 231 - updateIconImageStateViewData() 230 + updateIconsLoad() 232 231 updateIcons() 233 232 } 234 233 } ··· 285 284 if (iconImageState is IconImageState.Chooser) { 286 285 keyboardVisibility.set(false) 287 286 expandIconTypeSwitch.set(Unit) 288 - icons.set(ChangeRecordTypeIconStateViewData.Icons(emptyList())) 289 287 } 290 288 viewModelScope.launch { 291 - updateIconImageStateViewData() 289 + updateIconSelectorViewData() 290 + updateIconCategories(selectedIndex = 0) 291 + updateIconsLoad() 292 292 updateIcons() 293 293 } 294 294 } ··· 301 301 iconSearchJob = viewModelScope.launch { 302 302 iconSearch = search 303 303 delay(500) 304 - updateIconImageStateViewData() 305 304 updateIcons() 306 305 } 307 306 } ··· 507 506 icons.set(data) 508 507 } 509 508 509 + private fun updateIconsLoad() { 510 + val items = listOf(LoaderViewData()) 511 + val data = ChangeRecordTypeIconStateViewData.Icons(items) 512 + icons.set(data) 513 + } 514 + 510 515 private suspend fun loadIconsViewData(): ChangeRecordTypeIconStateViewData { 511 516 return viewDataInteractor.getIconsViewData( 512 517 newColor = newColor, ··· 537 542 return changeRecordTypeMapper.mapToIconSwitchViewData(iconType) 538 543 } 539 544 540 - private suspend fun updateIconImageStateViewData() { 541 - val data = loadIconImageStateViewData() 542 - iconImageStateViewData.set(data) 545 + private suspend fun updateIconSelectorViewData() { 546 + val data = loadIconSelectorViewData() 547 + iconSelectorViewData.set(data) 543 548 } 544 549 545 - private suspend fun loadIconImageStateViewData(): ChangeRecordTypeIconImageStateViewData { 546 - return changeRecordTypeMapper.mapToIconImageStateViewData( 550 + private suspend fun loadIconSelectorViewData(): ChangeRecordTypeIconSelectorStateViewData { 551 + return changeRecordTypeMapper.mapToIconSelectorViewData( 547 552 iconImageState = iconImageState, 548 553 iconType = iconType, 549 554 isDarkTheme = prefsInteractor.getDarkMode(),