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.

adding icon category selector

razeeman (Apr 18, 2021, 12:25 PM +0300) 53a4945b 31942b36

+265 -39
+44 -10
core/src/main/java/com/example/util/simpletimetracker/core/mapper/EmojiMapper.kt
··· 4 4 import com.example.util.simpletimetracker.core.repo.EmojiRepo 5 5 import com.example.util.simpletimetracker.core.repo.ResourceRepo 6 6 import com.example.util.simpletimetracker.domain.model.EmojiCategory 7 + import com.example.util.simpletimetracker.domain.model.EmojiType 7 8 import javax.inject.Inject 8 9 import javax.inject.Singleton 9 10 ··· 13 14 private val resourceRepo: ResourceRepo 14 15 ) { 15 16 16 - fun getAvailableEmojis(): List<EmojiCategory> = listOf( 17 - EmojiCategory(resourceRepo.getString(R.string.emojiGroupSmileys), repo.getGroupSmileys()), 18 - EmojiCategory(resourceRepo.getString(R.string.emojiGroupPeople), repo.getGroupPeople()), 19 - EmojiCategory(resourceRepo.getString(R.string.emojiGroupAnimals), repo.getGroupAnimals()), 20 - EmojiCategory(resourceRepo.getString(R.string.emojiGroupFood), repo.getGroupFood()), 21 - EmojiCategory(resourceRepo.getString(R.string.emojiGroupTravel), repo.getGroupTravel()), 22 - EmojiCategory(resourceRepo.getString(R.string.emojiGroupActivities), repo.getGroupActivities()), 23 - EmojiCategory(resourceRepo.getString(R.string.emojiGroupObjects), repo.getGroupObjects()), 24 - EmojiCategory(resourceRepo.getString(R.string.emojiGroupSymbols), repo.getGroupSymbols()), 25 - EmojiCategory(resourceRepo.getString(R.string.emojiGroupFlags), repo.getGroupFlags()) 17 + fun getAvailableEmojiCategories(): List<EmojiCategory> = listOf( 18 + EmojiCategory( 19 + EmojiType.SMILEYS, resourceRepo.getString(R.string.emojiGroupSmileys), "\uD83D\uDE00" 20 + ), 21 + EmojiCategory( 22 + EmojiType.PEOPLE, resourceRepo.getString(R.string.emojiGroupPeople), "\uD83D\uDC4B" 23 + ), 24 + EmojiCategory( 25 + EmojiType.ANIMALS, resourceRepo.getString(R.string.emojiGroupAnimals), "\uD83D\uDC35" 26 + ), 27 + EmojiCategory( 28 + EmojiType.FOOD, resourceRepo.getString(R.string.emojiGroupFood), "\uD83C\uDF47" 29 + ), 30 + EmojiCategory( 31 + EmojiType.TRAVEL, resourceRepo.getString(R.string.emojiGroupTravel), "\uD83C\uDF0D" 32 + ), 33 + EmojiCategory( 34 + EmojiType.ACTIVITIES, resourceRepo.getString(R.string.emojiGroupActivities), "\uD83C\uDF83" 35 + ), 36 + EmojiCategory( 37 + EmojiType.OBJECTS, resourceRepo.getString(R.string.emojiGroupObjects), "\uD83D\uDC53" 38 + ), 39 + EmojiCategory( 40 + EmojiType.SYMBOLS, resourceRepo.getString(R.string.emojiGroupSymbols), "\uD83C\uDFE7" 41 + ), 42 + EmojiCategory( 43 + EmojiType.FLAGS, resourceRepo.getString(R.string.emojiGroupFlags), "\uD83C\uDFC1" 44 + ) 26 45 ) 46 + 47 + fun getAvailableEmojis(): Map<EmojiCategory, List<String>> = 48 + getAvailableEmojiCategories().map { it to mapTypeToCodes(it.type) }.toMap() 27 49 28 50 fun hasSkinToneVariations(codes: String): Boolean = 29 51 codes.contains(EmojiRepo.SKIN_TONE) ··· 72 94 private fun removeSameSkinToneReplacement(codes: String): String { 73 95 return codes.replaceAfter(EmojiRepo.SAME_TONE_REPLACEMENT, "") 74 96 .replace(EmojiRepo.SAME_TONE_REPLACEMENT, "") 97 + } 98 + 99 + private fun mapTypeToCodes(type: EmojiType): List<String> = when (type) { 100 + EmojiType.SMILEYS -> repo.getGroupSmileys() 101 + EmojiType.PEOPLE -> repo.getGroupPeople() 102 + EmojiType.ANIMALS -> repo.getGroupAnimals() 103 + EmojiType.FOOD -> repo.getGroupFood() 104 + EmojiType.TRAVEL -> repo.getGroupTravel() 105 + EmojiType.ACTIVITIES -> repo.getGroupActivities() 106 + EmojiType.OBJECTS -> repo.getGroupObjects() 107 + EmojiType.SYMBOLS -> repo.getGroupSymbols() 108 + EmojiType.FLAGS -> repo.getGroupFlags() 75 109 } 76 110 }
+2 -1
domain/src/main/java/com/example/util/simpletimetracker/domain/model/EmojiCategory.kt
··· 1 1 package com.example.util.simpletimetracker.domain.model 2 2 3 3 data class EmojiCategory( 4 + val type: EmojiType, 4 5 val name: String, 5 - val emojiCodes: List<String> 6 + val emojiCode: String 6 7 )
+13
domain/src/main/java/com/example/util/simpletimetracker/domain/model/EmojiType.kt
··· 1 + package com.example.util.simpletimetracker.domain.model 2 + 3 + enum class EmojiType { 4 + SMILEYS, 5 + PEOPLE, 6 + ANIMALS, 7 + FOOD, 8 + TRAVEL, 9 + ACTIVITIES, 10 + OBJECTS, 11 + SYMBOLS, 12 + FLAGS 13 + }
+20
feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/adapter/ChangeRecordTypeIconCategoryAdapterDelegate.kt
··· 1 + package com.example.util.simpletimetracker.feature_change_record_type.adapter 2 + 3 + import com.example.util.simpletimetracker.core.adapter.createRecyclerAdapterDelegate 4 + import com.example.util.simpletimetracker.core.extension.setOnClickWith 5 + import com.example.util.simpletimetracker.feature_change_record_type.R 6 + import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeEmojiCategoryViewData 7 + import kotlinx.android.synthetic.main.change_record_type_item_icon_category_layout.view.tvChangeRecordTypeEmojiCategoryItem 8 + 9 + fun createChangeRecordTypeIconCategoryAdapterDelegate( 10 + onItemClick: ((ChangeRecordTypeEmojiCategoryViewData) -> Unit) 11 + ) = createRecyclerAdapterDelegate<ChangeRecordTypeEmojiCategoryViewData>( 12 + R.layout.change_record_type_item_icon_category_layout 13 + ) { itemView, item, _ -> 14 + 15 + with(itemView) { 16 + item as ChangeRecordTypeEmojiCategoryViewData 17 + tvChangeRecordTypeEmojiCategoryItem.text = item.emoji 18 + setOnClickWith(item, onItemClick) 19 + } 20 + }
+18
feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/adapter/ChangeRecordTypeIconCategoryInfoAdapterDelegate.kt
··· 1 + package com.example.util.simpletimetracker.feature_change_record_type.adapter 2 + 3 + import com.example.util.simpletimetracker.core.adapter.createRecyclerAdapterDelegate 4 + import com.example.util.simpletimetracker.feature_change_record_type.R 5 + import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconCategoryInfoViewData 6 + import kotlinx.android.synthetic.main.change_record_type_item_icon_category_info_layout.view.tvChangeRecordTypeIconCategoryInfoItem 7 + 8 + fun createChangeRecordTypeIconCategoryInfoAdapterDelegate() = 9 + createRecyclerAdapterDelegate<ChangeRecordTypeIconCategoryInfoViewData>( 10 + R.layout.change_record_type_item_icon_category_info_layout 11 + ) { itemView, item, _ -> 12 + 13 + with(itemView) { 14 + item as ChangeRecordTypeIconCategoryInfoViewData 15 + 16 + tvChangeRecordTypeIconCategoryInfoItem.text = item.text 17 + } 18 + }
+7
feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/interactor/ChangeRecordTypeViewDataInteractor.kt
··· 87 87 IconType.EMOJI -> mapper.mapIconEmojiData(newColorId, isDarkTheme) 88 88 } 89 89 } 90 + 91 + fun getIconCategoriesViewData(iconType: IconType): List<ViewHolderType> { 92 + return when (iconType) { 93 + IconType.IMAGE -> emptyList() 94 + IconType.EMOJI -> mapper.mapIconEmojiCategories() 95 + } 96 + } 90 97 }
+33 -16
feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/mapper/ChangeRecordTypeMapper.kt
··· 9 9 import com.example.util.simpletimetracker.core.mapper.TimeMapper 10 10 import com.example.util.simpletimetracker.core.repo.ResourceRepo 11 11 import com.example.util.simpletimetracker.core.viewData.EmojiViewData 12 + import com.example.util.simpletimetracker.domain.model.EmojiCategory 12 13 import com.example.util.simpletimetracker.domain.model.IconType 13 14 import com.example.util.simpletimetracker.feature_change_record_type.R 15 + import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeEmojiCategoryViewData 16 + import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconCategoryInfoViewData 14 17 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconTypeViewData 15 18 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconViewData 16 19 import com.example.util.simpletimetracker.navigation.params.EmojiSelectionDialogParams ··· 52 55 newColorId: Int, 53 56 isDarkTheme: Boolean 54 57 ): List<ViewHolderType> { 55 - return iconMapper.availableIconsNames 56 - .map { (iconName, iconResId) -> 57 - ChangeRecordTypeIconViewData( 58 - iconName = iconName, 59 - iconResId = iconResId, 60 - colorInt = newColorId 61 - .let { colorMapper.mapToColorResId(it, isDarkTheme) } 62 - .let(resourceRepo::getColor) 63 - ) 64 - } 58 + return iconMapper.availableIconsNames.map { (iconName, iconResId) -> 59 + ChangeRecordTypeIconViewData( 60 + iconName = iconName, 61 + iconResId = iconResId, 62 + colorInt = newColorId 63 + .let { colorMapper.mapToColorResId(it, isDarkTheme) } 64 + .let(resourceRepo::getColor) 65 + ) 66 + } 65 67 } 66 68 67 69 fun mapIconEmojiData( 68 70 newColorId: Int, 69 71 isDarkTheme: Boolean 70 72 ): List<ViewHolderType> { 71 - return emojiMapper.getAvailableEmojis() 72 - .map { category -> 73 - listOf(InfoViewData(category.name)) + category.emojiCodes.map { codes -> 74 - mapEmojiViewData(codes, newColorId, isDarkTheme) 75 - } 76 - }.flatten() 73 + return emojiMapper.getAvailableEmojis().map { (category, codes) -> 74 + listOf(mapEmojiCategoryHintViewData(category)) + codes.map { code -> 75 + mapEmojiViewData(code, newColorId, isDarkTheme) 76 + } 77 + }.flatten() 78 + } 79 + 80 + fun mapIconEmojiCategories(): List<ViewHolderType> { 81 + return emojiMapper.getAvailableEmojiCategories().map { 82 + ChangeRecordTypeEmojiCategoryViewData( 83 + type = it.type, 84 + emoji = it.emojiCode 85 + ) 86 + } 77 87 } 78 88 79 89 fun mapToIconSwitchViewData(iconType: IconType): List<ViewHolderType> { ··· 117 127 colorInt = newColorId 118 128 .let { colorMapper.mapToColorResId(it, isDarkTheme) } 119 129 .let(resourceRepo::getColor) 130 + ) 131 + } 132 + 133 + private fun mapEmojiCategoryHintViewData(category: EmojiCategory): ChangeRecordTypeIconCategoryInfoViewData { 134 + return ChangeRecordTypeIconCategoryInfoViewData( 135 + type = category.type, 136 + text = category.name 120 137 ) 121 138 } 122 139 }
+30 -8
feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/view/ChangeRecordTypeFragment.kt
··· 9 9 import com.example.util.simpletimetracker.core.adapter.BaseRecyclerAdapter 10 10 import com.example.util.simpletimetracker.core.adapter.color.createColorAdapterDelegate 11 11 import com.example.util.simpletimetracker.core.adapter.divider.createDividerAdapterDelegate 12 + import com.example.util.simpletimetracker.core.adapter.emoji.createEmojiAdapterDelegate 12 13 import com.example.util.simpletimetracker.core.adapter.empty.createEmptyAdapterDelegate 13 14 import com.example.util.simpletimetracker.core.adapter.info.createInfoAdapterDelegate 14 15 import com.example.util.simpletimetracker.core.base.BaseFragment 15 16 import com.example.util.simpletimetracker.core.di.BaseViewModelFactory 16 17 import com.example.util.simpletimetracker.core.dialog.DurationDialogListener 18 + import com.example.util.simpletimetracker.core.dialog.EmojiSelectionDialogListener 17 19 import com.example.util.simpletimetracker.core.extension.dpToPx 18 20 import com.example.util.simpletimetracker.core.extension.hideKeyboard 19 21 import com.example.util.simpletimetracker.core.extension.observeOnce ··· 29 31 import com.example.util.simpletimetracker.core.viewData.RecordTypeViewData 30 32 import com.example.util.simpletimetracker.feature_change_record_type.R 31 33 import com.example.util.simpletimetracker.feature_change_record_type.adapter.createChangeRecordTypeCategoryAdapterDelegate 32 - import com.example.util.simpletimetracker.core.adapter.emoji.createEmojiAdapterDelegate 33 - import com.example.util.simpletimetracker.core.dialog.EmojiSelectionDialogListener 34 34 import com.example.util.simpletimetracker.feature_change_record_type.adapter.createChangeRecordTypeIconAdapterDelegate 35 + import com.example.util.simpletimetracker.feature_change_record_type.adapter.createChangeRecordTypeIconCategoryAdapterDelegate 36 + import com.example.util.simpletimetracker.feature_change_record_type.adapter.createChangeRecordTypeIconCategoryInfoAdapterDelegate 35 37 import com.example.util.simpletimetracker.feature_change_record_type.di.ChangeRecordTypeComponentProvider 38 + import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeScrollViewData 36 39 import com.example.util.simpletimetracker.feature_change_record_type.viewModel.ChangeRecordTypeViewModel 37 40 import com.example.util.simpletimetracker.navigation.params.ChangeRecordTypeParams 38 41 import com.google.android.flexbox.FlexDirection ··· 55 58 import kotlinx.android.synthetic.main.change_record_type_fragment.rvChangeRecordTypeCategories 56 59 import kotlinx.android.synthetic.main.change_record_type_fragment.rvChangeRecordTypeColor 57 60 import kotlinx.android.synthetic.main.change_record_type_fragment.rvChangeRecordTypeIcon 61 + import kotlinx.android.synthetic.main.change_record_type_fragment.rvChangeRecordTypeIconCategory 58 62 import kotlinx.android.synthetic.main.change_record_type_fragment.tvChangeRecordTypeGoalTimeTime 59 63 import javax.inject.Inject 60 64 ··· 75 79 } 76 80 private val iconsAdapter: BaseRecyclerAdapter by lazy { 77 81 BaseRecyclerAdapter( 78 - createInfoAdapterDelegate(), 79 82 createChangeRecordTypeIconAdapterDelegate(viewModel::onIconClick), 80 - createEmojiAdapterDelegate(viewModel::onEmojiClick) 83 + createEmojiAdapterDelegate(viewModel::onEmojiClick), 84 + createChangeRecordTypeIconCategoryInfoAdapterDelegate() 85 + ) 86 + } 87 + private val iconCategoriesAdapter: BaseRecyclerAdapter by lazy { 88 + BaseRecyclerAdapter( 89 + createChangeRecordTypeIconCategoryAdapterDelegate(viewModel::onIconCategoryClick) 81 90 ) 82 91 } 83 92 private val categoriesAdapter: BaseRecyclerAdapter by lazy { ··· 130 139 adapter = iconsAdapter 131 140 } 132 141 142 + rvChangeRecordTypeIconCategory.apply { 143 + layoutManager = FlexboxLayoutManager(context).apply { 144 + flexDirection = FlexDirection.ROW 145 + justifyContent = JustifyContent.CENTER 146 + flexWrap = FlexWrap.NOWRAP 147 + } 148 + adapter = iconCategoriesAdapter 149 + } 150 + 133 151 rvChangeRecordTypeCategories.apply { 134 152 layoutManager = FlexboxLayoutManager(requireContext()).apply { 135 153 flexDirection = FlexDirection.ROW ··· 153 171 154 172 override fun initViewModel(): Unit = with(viewModel) { 155 173 extra = params 156 - deleteIconVisibility.observeOnce( 157 - viewLifecycleOwner, 158 - btnChangeRecordTypeDelete::visible::set 159 - ) 174 + deleteIconVisibility.observeOnce(viewLifecycleOwner, btnChangeRecordTypeDelete::visible::set) 160 175 saveButtonEnabled.observe(viewLifecycleOwner, btnChangeRecordTypeSave::setEnabled) 161 176 deleteButtonEnabled.observe(viewLifecycleOwner, btnChangeRecordTypeDelete::setEnabled) 162 177 recordType.observeOnce(viewLifecycleOwner, ::updateUi) 163 178 recordType.observe(viewLifecycleOwner, ::updatePreview) 164 179 colors.observe(viewLifecycleOwner, colorsAdapter::replace) 165 180 icons.observe(viewLifecycleOwner, iconsAdapter::replace) 181 + iconCategories.observe(viewLifecycleOwner, iconCategoriesAdapter::replace) 166 182 iconsTypeViewData.observe(viewLifecycleOwner, btnChangeRecordTypeIconSwitch.adapter::replace) 167 183 categories.observe(viewLifecycleOwner, categoriesAdapter::replace) 168 184 goalTimeViewData.observe(viewLifecycleOwner, tvChangeRecordTypeGoalTimeTime::setText) ··· 186 202 } 187 203 keyboardVisibility.observe(viewLifecycleOwner) { visible -> 188 204 if (visible) showKeyboard(etChangeRecordTypeName) else hideKeyboard() 205 + } 206 + iconsScrollPosition.observe(viewLifecycleOwner) { 207 + if (it is ChangeRecordTypeScrollViewData.ScrollTo) { 208 + rvChangeRecordTypeIcon.scrollToPosition(it.position) 209 + onScrolled() 210 + } 189 211 } 190 212 } 191 213
+14
feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/viewData/ChangeRecordTypeEmojiCategoryViewData.kt
··· 1 + package com.example.util.simpletimetracker.feature_change_record_type.viewData 2 + 3 + import com.example.util.simpletimetracker.core.adapter.ViewHolderType 4 + import com.example.util.simpletimetracker.domain.model.EmojiType 5 + 6 + data class ChangeRecordTypeEmojiCategoryViewData( 7 + val type: EmojiType, 8 + val emoji: String 9 + ): ViewHolderType { 10 + 11 + override fun getUniqueId(): Long = type.ordinal.toLong() 12 + 13 + override fun isValidType(other: ViewHolderType): Boolean = other is ChangeRecordTypeEmojiCategoryViewData 14 + }
+14
feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/viewData/ChangeRecordTypeIconCategoryInfoViewData.kt
··· 1 + package com.example.util.simpletimetracker.feature_change_record_type.viewData 2 + 3 + import com.example.util.simpletimetracker.core.adapter.ViewHolderType 4 + import com.example.util.simpletimetracker.domain.model.EmojiType 5 + 6 + data class ChangeRecordTypeIconCategoryInfoViewData( 7 + val type: EmojiType, 8 + val text: String 9 + ) : ViewHolderType { 10 + 11 + override fun getUniqueId(): Long = type.ordinal.toLong() 12 + 13 + override fun isValidType(other: ViewHolderType): Boolean = other is ChangeRecordTypeIconCategoryInfoViewData 14 + }
+7
feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/viewData/ChangeRecordTypeScrollViewData.kt
··· 1 + package com.example.util.simpletimetracker.feature_change_record_type.viewData 2 + 3 + sealed class ChangeRecordTypeScrollViewData { 4 + 5 + data class ScrollTo(val position: Int) : ChangeRecordTypeScrollViewData() 6 + object NoScroll : ChangeRecordTypeScrollViewData() 7 + }
+32
feature_change_record_type/src/main/java/com/example/util/simpletimetracker/feature_change_record_type/viewModel/ChangeRecordTypeViewModel.kt
··· 5 5 import androidx.lifecycle.ViewModel 6 6 import androidx.lifecycle.viewModelScope 7 7 import com.example.util.simpletimetracker.core.adapter.ViewHolderType 8 + import com.example.util.simpletimetracker.core.extension.set 8 9 import com.example.util.simpletimetracker.core.interactor.NotificationGoalTimeInteractor 9 10 import com.example.util.simpletimetracker.core.interactor.NotificationTypeInteractor 10 11 import com.example.util.simpletimetracker.core.interactor.RemoveRunningRecordMediator ··· 30 31 import com.example.util.simpletimetracker.feature_change_record_type.R 31 32 import com.example.util.simpletimetracker.feature_change_record_type.interactor.ChangeRecordTypeViewDataInteractor 32 33 import com.example.util.simpletimetracker.feature_change_record_type.mapper.ChangeRecordTypeMapper 34 + import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeEmojiCategoryViewData 35 + import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconCategoryInfoViewData 33 36 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconTypeViewData 34 37 import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeIconViewData 38 + import com.example.util.simpletimetracker.feature_change_record_type.viewData.ChangeRecordTypeScrollViewData 35 39 import com.example.util.simpletimetracker.navigation.Notification 36 40 import com.example.util.simpletimetracker.navigation.Router 37 41 import com.example.util.simpletimetracker.navigation.Screen ··· 82 86 initial 83 87 } 84 88 } 89 + val iconCategories: LiveData<List<ViewHolderType>> by lazy { 90 + return@lazy MutableLiveData<List<ViewHolderType>>().let { initial -> 91 + viewModelScope.launch { initial.value = loadIconCategoriesViewData() } 92 + initial 93 + } 94 + } 85 95 val iconsTypeViewData: LiveData<List<ViewHolderType>> by lazy { 86 96 return@lazy MutableLiveData(loadIconsTypeViewData()) 87 97 } ··· 109 119 val saveButtonEnabled: LiveData<Boolean> = MutableLiveData(true) 110 120 val deleteIconVisibility: LiveData<Boolean> by lazy { MutableLiveData(extra.id != 0L) } 111 121 val keyboardVisibility: LiveData<Boolean> by lazy { MutableLiveData(extra.id == 0L) } 122 + val iconsScrollPosition: LiveData<ChangeRecordTypeScrollViewData> = MutableLiveData() 112 123 113 124 private var iconType: IconType = IconType.IMAGE 114 125 private var initialCategories: List<Long> = emptyList() ··· 181 192 viewModelScope.launch { 182 193 iconType = viewData.iconType 183 194 updateIconsTypeViewData() 195 + updateIconCategories() 184 196 updateIcons() 185 197 } 186 198 } 187 199 200 + fun onIconCategoryClick(viewData: ChangeRecordTypeEmojiCategoryViewData) { 201 + icons.value 202 + ?.indexOfFirst { (it as? ChangeRecordTypeIconCategoryInfoViewData)?.type == viewData.type } 203 + ?.let { ChangeRecordTypeScrollViewData.ScrollTo(it) } 204 + ?.let { iconsScrollPosition.set(it) } 205 + } 206 + 188 207 fun onIconClick(item: ChangeRecordTypeIconViewData) { 189 208 viewModelScope.launch { 190 209 if (item.iconName != newIconName) { ··· 292 311 } 293 312 } 294 313 314 + fun onScrolled() { 315 + iconsScrollPosition.set(ChangeRecordTypeScrollViewData.NoScroll) 316 + } 317 + 295 318 private fun openEmojiSelectionDialog(item: EmojiViewData) { 296 319 val params = changeRecordTypeMapper.mapEmojiSelectionParams( 297 320 colorId = newColorId, ··· 370 393 371 394 private suspend fun loadIconsViewData(): List<ViewHolderType> { 372 395 return viewDataInteractor.getIconsViewData(newColorId, iconType) 396 + } 397 + 398 + private fun updateIconCategories() = viewModelScope.launch { 399 + val data = loadIconCategoriesViewData() 400 + (iconCategories as MutableLiveData).value = data 401 + } 402 + 403 + private fun loadIconCategoriesViewData(): List<ViewHolderType> { 404 + return viewDataInteractor.getIconCategoriesViewData(iconType) 373 405 } 374 406 375 407 private fun updateIconsTypeViewData() {
+8 -4
feature_change_record_type/src/main/res/layout/change_record_type_fragment.xml
··· 274 274 android:layout_height="wrap_content" 275 275 app:layout_scrollFlags="scroll" /> 276 276 277 - <androidx.appcompat.widget.AppCompatTextView 277 + <androidx.recyclerview.widget.RecyclerView 278 + android:id="@+id/rvChangeRecordTypeIconCategory" 278 279 android:layout_width="match_parent" 279 280 android:layout_height="wrap_content" 280 - android:gravity="center" 281 - android:text="TODO select icon category and scroll to it" 282 - app:layout_scrollFlags="scroll|enterAlways" /> 281 + app:layout_scrollFlags="scroll|enterAlways" 282 + android:layout_marginStart="8dp" 283 + android:layout_marginEnd="8dp" 284 + android:overScrollMode="never" 285 + tools:itemCount="1" 286 + tools:listitem="@layout/change_record_type_item_icon_category_layout" /> 283 287 284 288 </com.google.android.material.appbar.AppBarLayout> 285 289
+10
feature_change_record_type/src/main/res/layout/change_record_type_item_icon_category_info_layout.xml
··· 1 + <?xml version="1.0" encoding="utf-8"?> 2 + <androidx.appcompat.widget.AppCompatTextView xmlns:android="http://schemas.android.com/apk/res/android" 3 + xmlns:tools="http://schemas.android.com/tools" 4 + android:id="@+id/tvChangeRecordTypeIconCategoryInfoItem" 5 + android:layout_width="match_parent" 6 + android:layout_height="wrap_content" 7 + android:gravity="center" 8 + android:textColor="?appTextHintColor" 9 + android:textStyle="bold" 10 + tools:text="Hint text" />
+13
feature_change_record_type/src/main/res/layout/change_record_type_item_icon_category_layout.xml
··· 1 + <?xml version="1.0" encoding="utf-8"?> 2 + <androidx.emoji.widget.EmojiAppCompatTextView xmlns:android="http://schemas.android.com/apk/res/android" 3 + xmlns:app="http://schemas.android.com/apk/res-auto" 4 + xmlns:tools="http://schemas.android.com/tools" 5 + android:id="@+id/tvChangeRecordTypeEmojiCategoryItem" 6 + android:layout_width="match_parent" 7 + android:layout_height="24dp" 8 + android:layout_marginVertical="4dp" 9 + android:background="?selectableItemBackgroundBorderless" 10 + android:gravity="center" 11 + android:textColor="?appLightTextColor" 12 + app:autoSizeTextType="uniform" 13 + tools:text="😀" />