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.

add search comment

razeeman (Jun 17, 2023, 2:57 PM +0300) b74d5de3 e59ecfe6

+388 -93
+55
features/feature_change_record/src/main/res/layout/change_record_comment_field_item.xml
··· 1 + <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 + xmlns:app="http://schemas.android.com/apk/res-auto" 3 + android:layout_width="match_parent" 4 + android:layout_height="wrap_content" 5 + android:paddingBottom="6dp"> 6 + 7 + <com.google.android.material.textfield.TextInputLayout 8 + android:id="@+id/inputChangeRecordCommentField" 9 + style="@style/ChangeItemInputField" 10 + android:layout_width="0dp" 11 + android:layout_height="wrap_content" 12 + android:layout_marginStart="2dp" 13 + android:layout_marginEnd="2dp" 14 + app:layout_constraintEnd_toStartOf="@id/btnChangeRecordSearchCommentField" 15 + app:layout_constraintStart_toStartOf="parent" 16 + app:layout_constraintTop_toTopOf="parent" 17 + app:layout_goneMarginEnd="20dp"> 18 + 19 + <com.google.android.material.textfield.TextInputEditText 20 + android:id="@+id/etChangeRecordCommentField" 21 + style="@style/EditTextMultiLine" 22 + android:layout_width="match_parent" 23 + android:layout_height="wrap_content" 24 + android:hint="@string/records_all_search_comment" /> 25 + 26 + </com.google.android.material.textfield.TextInputLayout> 27 + 28 + <androidx.cardview.widget.CardView 29 + android:id="@+id/btnChangeRecordSearchCommentField" 30 + style="@style/InputFieldCard" 31 + android:layout_width="36dp" 32 + android:layout_height="36dp" 33 + android:layout_marginTop="2dp" 34 + app:layout_constraintDimensionRatio="h,1:1" 35 + app:layout_constraintEnd_toEndOf="parent" 36 + app:layout_constraintTop_toTopOf="parent"> 37 + 38 + <androidx.appcompat.widget.AppCompatTextView 39 + style="@style/ButtonTimeAdjust" 40 + android:layout_width="match_parent" 41 + android:layout_height="match_parent" 42 + android:text="" /> 43 + 44 + <androidx.appcompat.widget.AppCompatImageView 45 + android:id="@+id/ivChangeRecordSearchCommentField" 46 + android:layout_width="match_parent" 47 + android:layout_height="match_parent" 48 + android:layout_margin="4dp" 49 + android:background="@drawable/search" 50 + android:backgroundTint="?colorSecondary" 51 + android:scaleType="center" /> 52 + 53 + </androidx.cardview.widget.CardView> 54 + 55 + </androidx.constraintlayout.widget.ConstraintLayout>
+114 -65
features/feature_change_record/src/main/res/layout/change_record_core_layout.xml
··· 304 304 app:barrierDirection="bottom" 305 305 app:constraint_referenced_ids="fieldChangeRecordComment, fieldChangeRecordAction" /> 306 306 307 - <androidx.core.widget.NestedScrollView 307 + <FrameLayout 308 308 android:id="@+id/containerChangeRecordComment" 309 309 android:layout_width="match_parent" 310 310 android:layout_height="0dp" 311 - android:scrollbars="vertical" 312 311 android:visibility="gone" 313 312 app:layout_constraintBottom_toTopOf="@id/btnChangeRecordSave" 314 313 app:layout_constraintTop_toBottomOf="@id/barrierChangeRecord" 315 314 tools:visibility="visible"> 316 315 317 - <androidx.constraintlayout.widget.ConstraintLayout 316 + <androidx.core.widget.NestedScrollView 317 + android:id="@+id/containerChangeRecordCommentField" 318 318 android:layout_width="match_parent" 319 - android:layout_height="wrap_content" 320 - android:orientation="vertical"> 319 + android:layout_height="match_parent" 320 + android:scrollbars="vertical" 321 + android:visibility="gone" 322 + app:layout_constraintBottom_toTopOf="@id/btnChangeRecordSave" 323 + app:layout_constraintTop_toBottomOf="@id/barrierChangeRecord" 324 + tools:visibility="visible"> 321 325 322 - <com.google.android.material.textfield.TextInputLayout 323 - android:id="@+id/inputChangeRecordComment" 324 - style="@style/ChangeItemInputField" 325 - android:layout_width="0dp" 326 - android:layout_height="wrap_content" 327 - android:layout_marginStart="20dp" 328 - android:layout_marginEnd="2dp" 329 - app:layout_constraintEnd_toStartOf="@id/btnChangeRecordFavouriteComment" 330 - app:layout_constraintStart_toStartOf="parent" 331 - app:layout_constraintTop_toTopOf="parent" 332 - app:layout_goneMarginEnd="20dp"> 333 - 334 - <com.google.android.material.textfield.TextInputEditText 335 - android:id="@+id/etChangeRecordComment" 336 - style="@style/EditTextMultiLine" 337 - android:layout_width="match_parent" 338 - android:layout_height="wrap_content" 339 - android:hint="@string/change_record_comment_hint" /> 340 - 341 - </com.google.android.material.textfield.TextInputLayout> 342 - 343 - <androidx.cardview.widget.CardView 344 - android:id="@+id/btnChangeRecordFavouriteComment" 345 - style="@style/InputFieldCard" 346 - android:layout_width="36dp" 347 - android:layout_height="36dp" 348 - android:layout_marginTop="2dp" 349 - android:layout_marginEnd="18dp" 350 - app:layout_constraintDimensionRatio="h,1:1" 351 - app:layout_constraintEnd_toEndOf="parent" 352 - app:layout_constraintTop_toTopOf="parent"> 353 - 354 - <androidx.appcompat.widget.AppCompatTextView 355 - style="@style/ButtonTimeAdjust" 356 - android:layout_width="match_parent" 357 - android:layout_height="match_parent" 358 - android:text="" /> 359 - 360 - <androidx.appcompat.widget.AppCompatImageView 361 - android:id="@+id/ivChangeRecordFavouriteComment" 362 - android:layout_width="match_parent" 363 - android:layout_height="match_parent" 364 - android:layout_margin="4dp" 365 - android:background="@drawable/star" 366 - android:backgroundTint="?appInactiveColor" 367 - android:scaleType="center" /> 368 - 369 - </androidx.cardview.widget.CardView> 370 - 371 - <androidx.recyclerview.widget.RecyclerView 372 - android:id="@+id/rvChangeRecordLastComments" 326 + <androidx.constraintlayout.widget.ConstraintLayout 373 327 android:layout_width="match_parent" 374 328 android:layout_height="wrap_content" 375 - android:layout_marginHorizontal="20dp" 376 - android:nestedScrollingEnabled="false" 377 - android:overScrollMode="never" 378 - app:layout_constraintBottom_toBottomOf="parent" 379 - app:layout_constraintTop_toBottomOf="@id/inputChangeRecordComment" 380 - tools:itemCount="3" 381 - tools:listitem="@layout/change_record_comment_item" /> 329 + android:orientation="vertical"> 382 330 383 - </androidx.constraintlayout.widget.ConstraintLayout> 331 + <com.google.android.material.textfield.TextInputLayout 332 + android:id="@+id/inputChangeRecordComment" 333 + style="@style/ChangeItemInputField" 334 + android:layout_width="0dp" 335 + android:layout_height="wrap_content" 336 + android:layout_marginStart="20dp" 337 + android:layout_marginEnd="2dp" 338 + app:layout_constraintEnd_toStartOf="@id/btnChangeRecordSearchComment" 339 + app:layout_constraintStart_toStartOf="parent" 340 + app:layout_constraintTop_toTopOf="parent" 341 + app:layout_goneMarginEnd="20dp"> 384 342 385 - </androidx.core.widget.NestedScrollView> 343 + <com.google.android.material.textfield.TextInputEditText 344 + android:id="@+id/etChangeRecordComment" 345 + style="@style/EditTextMultiLine" 346 + android:layout_width="match_parent" 347 + android:layout_height="wrap_content" 348 + android:hint="@string/change_record_comment_hint" /> 349 + 350 + </com.google.android.material.textfield.TextInputLayout> 351 + 352 + <androidx.cardview.widget.CardView 353 + android:id="@+id/btnChangeRecordSearchComment" 354 + style="@style/InputFieldCard" 355 + android:layout_width="36dp" 356 + android:layout_height="36dp" 357 + android:layout_marginTop="2dp" 358 + android:layout_marginEnd="18dp" 359 + app:layout_constraintDimensionRatio="h,1:1" 360 + app:layout_constraintEnd_toEndOf="parent" 361 + app:layout_constraintTop_toTopOf="parent"> 362 + 363 + <androidx.appcompat.widget.AppCompatTextView 364 + style="@style/ButtonTimeAdjust" 365 + android:layout_width="match_parent" 366 + android:layout_height="match_parent" 367 + android:text="" /> 368 + 369 + <androidx.appcompat.widget.AppCompatImageView 370 + android:id="@+id/ivChangeRecordSearchComment" 371 + android:layout_width="match_parent" 372 + android:layout_height="match_parent" 373 + android:layout_margin="4dp" 374 + android:background="@drawable/search" 375 + android:backgroundTint="?appInactiveColor" 376 + android:scaleType="center" /> 377 + 378 + </androidx.cardview.widget.CardView> 379 + 380 + <androidx.cardview.widget.CardView 381 + android:id="@+id/btnChangeRecordFavouriteComment" 382 + style="@style/InputFieldCard" 383 + android:layout_width="36dp" 384 + android:layout_height="36dp" 385 + android:layout_marginEnd="18dp" 386 + app:layout_constraintDimensionRatio="h,1:1" 387 + app:layout_constraintEnd_toEndOf="parent" 388 + app:layout_constraintTop_toBottomOf="@id/btnChangeRecordSearchComment"> 389 + 390 + <androidx.appcompat.widget.AppCompatTextView 391 + style="@style/ButtonTimeAdjust" 392 + android:layout_width="match_parent" 393 + android:layout_height="match_parent" 394 + android:text="" /> 395 + 396 + <androidx.appcompat.widget.AppCompatImageView 397 + android:id="@+id/ivChangeRecordFavouriteComment" 398 + android:layout_width="match_parent" 399 + android:layout_height="match_parent" 400 + android:layout_margin="4dp" 401 + android:background="@drawable/star" 402 + android:backgroundTint="?appInactiveColor" 403 + android:scaleType="center" /> 404 + 405 + </androidx.cardview.widget.CardView> 406 + 407 + <androidx.recyclerview.widget.RecyclerView 408 + android:id="@+id/rvChangeRecordLastComments" 409 + android:layout_width="match_parent" 410 + android:layout_height="wrap_content" 411 + android:layout_marginHorizontal="19dp" 412 + android:nestedScrollingEnabled="false" 413 + android:overScrollMode="never" 414 + app:layout_constraintBottom_toBottomOf="parent" 415 + app:layout_constraintTop_toBottomOf="@id/inputChangeRecordComment" 416 + tools:itemCount="3" 417 + tools:listitem="@layout/change_record_comment_item" /> 418 + 419 + </androidx.constraintlayout.widget.ConstraintLayout> 420 + 421 + </androidx.core.widget.NestedScrollView> 422 + 423 + <androidx.recyclerview.widget.RecyclerView 424 + android:id="@+id/rvChangeRecordSearchComments" 425 + android:layout_width="match_parent" 426 + android:layout_height="match_parent" 427 + android:scrollbars="vertical" 428 + android:layout_marginHorizontal="18dp" 429 + android:visibility="gone" 430 + tools:itemCount="1" 431 + tools:listitem="@layout/change_record_comment_field_item" 432 + tools:visibility="gone" /> 433 + 434 + </FrameLayout> 386 435 387 436 <androidx.core.widget.NestedScrollView 388 437 android:id="@+id/containerChangeRecordAction"
+9
features/feature_views/src/main/res/drawable/search.xml
··· 1 + <vector xmlns:android="http://schemas.android.com/apk/res/android" 2 + android:width="24dp" 3 + android:height="24dp" 4 + android:viewportWidth="24" 5 + android:viewportHeight="24"> 6 + <path 7 + android:fillColor="#FF000000" 8 + android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/> 9 + </vector>
+1 -1
features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/adapter/ChangeRecordCommentAdapterDelegate.kt
··· 3 3 import com.example.util.simpletimetracker.feature_base_adapter.createRecyclerBindingAdapterDelegate 4 4 import com.example.util.simpletimetracker.feature_views.extension.setOnClickWith 5 5 import com.example.util.simpletimetracker.feature_change_record.databinding.ChangeRecordCommentItemBinding as Binding 6 - import com.example.util.simpletimetracker.feature_change_record.viewData.ChangeRecordCommentViewData as ViewData 6 + import com.example.util.simpletimetracker.feature_change_record.adapter.ChangeRecordCommentViewData as ViewData 7 7 8 8 fun createChangeRecordCommentAdapterDelegate( 9 9 onItemClick: ((ViewData) -> Unit),
+30
features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/adapter/ChangeRecordCommentFieldAdapterDelegate.kt
··· 1 + package com.example.util.simpletimetracker.feature_change_record.adapter 2 + 3 + import android.text.TextWatcher 4 + import androidx.core.widget.doAfterTextChanged 5 + import com.example.util.simpletimetracker.feature_base_adapter.createRecyclerBindingAdapterDelegate 6 + import com.example.util.simpletimetracker.feature_views.extension.setOnClick 7 + import com.example.util.simpletimetracker.feature_change_record.adapter.ChangeRecordCommentFieldViewData as ViewData 8 + import com.example.util.simpletimetracker.feature_change_record.databinding.ChangeRecordCommentFieldItemBinding as Binding 9 + 10 + fun createChangeRecordCommentFieldAdapterDelegate( 11 + afterTextChange: (String) -> Unit, 12 + onSearchClick: () -> Unit, 13 + ) = createRecyclerBindingAdapterDelegate<ViewData, Binding>( 14 + Binding::inflate 15 + ) { binding, item, _ -> 16 + 17 + with(binding) { 18 + item as ViewData 19 + 20 + if (item.text != etChangeRecordCommentField.text.toString()) { 21 + etChangeRecordCommentField.setText(item.text) 22 + } 23 + btnChangeRecordSearchCommentField.setOnClick { onSearchClick() } 24 + 25 + etChangeRecordCommentField.removeTextChangedListener(textWatcher) 26 + textWatcher = etChangeRecordCommentField.doAfterTextChanged { afterTextChange(it.toString()) } 27 + } 28 + } 29 + 30 + private var textWatcher: TextWatcher? = null
+14
features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/adapter/ChangeRecordCommentFieldViewData.kt
··· 1 + package com.example.util.simpletimetracker.feature_change_record.adapter 2 + 3 + import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType 4 + 5 + data class ChangeRecordCommentFieldViewData( 6 + val id: Long, 7 + val text: String, 8 + ) : ViewHolderType { 9 + 10 + override fun getUniqueId(): Long = id 11 + 12 + override fun isValidType(other: ViewHolderType): Boolean = 13 + other is ChangeRecordCommentFieldViewData 14 + }
+24
features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/adapter/ChangeRecordCommentViewData.kt
··· 1 + package com.example.util.simpletimetracker.feature_change_record.adapter 2 + 3 + import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType 4 + 5 + sealed class ChangeRecordCommentViewData : ViewHolderType { 6 + 7 + abstract val text: String 8 + 9 + override fun getUniqueId(): Long = text.hashCode().toLong() 10 + 11 + data class Last( 12 + override val text: String, 13 + ) : ChangeRecordCommentViewData() { 14 + 15 + override fun isValidType(other: ViewHolderType): Boolean = other is Last 16 + } 17 + 18 + data class Favourite( 19 + override val text: String, 20 + ) : ChangeRecordCommentViewData() { 21 + 22 + override fun isValidType(other: ViewHolderType): Boolean = other is Favourite 23 + } 24 + }
+31 -1
features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/interactor/ChangeRecordViewDataInteractor.kt
··· 13 13 import com.example.util.simpletimetracker.domain.model.Record 14 14 import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType 15 15 import com.example.util.simpletimetracker.feature_base_adapter.hint.HintViewData 16 + import com.example.util.simpletimetracker.feature_base_adapter.loader.LoaderViewData 16 17 import com.example.util.simpletimetracker.feature_change_record.R 18 + import com.example.util.simpletimetracker.feature_change_record.adapter.ChangeRecordCommentFieldViewData 17 19 import com.example.util.simpletimetracker.feature_change_record.mapper.ChangeRecordViewDataMapper 18 - import com.example.util.simpletimetracker.feature_change_record.viewData.ChangeRecordCommentViewData 20 + import com.example.util.simpletimetracker.feature_change_record.adapter.ChangeRecordCommentViewData 19 21 import com.example.util.simpletimetracker.feature_change_record.viewData.ChangeRecordFavCommentState 22 + import com.example.util.simpletimetracker.feature_change_record.viewData.ChangeRecordSearchCommentState 20 23 import com.example.util.simpletimetracker.feature_change_record.viewData.ChangeRecordViewData 21 24 import java.util.Locale 22 25 import javax.inject.Inject ··· 106 109 colorMapper.toInactiveColor(isDarkTheme) 107 110 }, 108 111 isVisible = comment.isNotEmpty(), 112 + ) 113 + } 114 + 115 + suspend fun getSearchCommentViewData( 116 + isEnabled: Boolean, 117 + isLoading: Boolean, 118 + search: String, 119 + ): ChangeRecordSearchCommentState { 120 + val items = mutableListOf<ViewHolderType>() 121 + 122 + ChangeRecordCommentFieldViewData( 123 + id = 1L, // Only one at the time. 124 + text = search, 125 + ).let(items::add) 126 + 127 + when { 128 + isLoading -> LoaderViewData().let(::listOf) 129 + search.isEmpty() -> emptyList() 130 + else -> { 131 + recordInteractor.searchComment(search) 132 + .map { ChangeRecordCommentViewData.Last(it.comment) } 133 + } 134 + }.let(items::addAll) 135 + 136 + return ChangeRecordSearchCommentState( 137 + enabled = isEnabled, 138 + items = items, 109 139 ) 110 140 } 111 141
+37
features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/view/ChangeRecordCore.kt
··· 19 19 import com.example.util.simpletimetracker.feature_base_adapter.empty.createEmptyAdapterDelegate 20 20 import com.example.util.simpletimetracker.feature_base_adapter.hint.createHintAdapterDelegate 21 21 import com.example.util.simpletimetracker.feature_base_adapter.info.createInfoAdapterDelegate 22 + import com.example.util.simpletimetracker.feature_base_adapter.loader.createLoaderAdapterDelegate 22 23 import com.example.util.simpletimetracker.feature_base_adapter.recordType.createRecordTypeAdapterDelegate 23 24 import com.example.util.simpletimetracker.feature_change_record.adapter.createChangeRecordCommentAdapterDelegate 25 + import com.example.util.simpletimetracker.feature_change_record.adapter.createChangeRecordCommentFieldAdapterDelegate 24 26 import com.example.util.simpletimetracker.feature_change_record.databinding.ChangeRecordCoreLayoutBinding 25 27 import com.example.util.simpletimetracker.feature_change_record.databinding.ChangeRecordPreviewLayoutBinding 26 28 import com.example.util.simpletimetracker.feature_change_record.viewData.ChangeRecordChooserState ··· 33 35 import com.example.util.simpletimetracker.feature_change_record.viewData.ChangeRecordSimpleViewData 34 36 import com.example.util.simpletimetracker.feature_change_record.model.TimeAdjustmentState 35 37 import com.example.util.simpletimetracker.feature_change_record.viewData.ChangeRecordFavCommentState 38 + import com.example.util.simpletimetracker.feature_change_record.viewData.ChangeRecordSearchCommentState 36 39 import com.example.util.simpletimetracker.feature_change_record.viewModel.ChangeRecordBaseViewModel 37 40 import com.example.util.simpletimetracker.feature_views.RecordSimpleView 38 41 import com.example.util.simpletimetracker.feature_views.extension.rotateDown ··· 73 76 createChangeRecordCommentAdapterDelegate(viewModel::onCommentClick), 74 77 ) 75 78 } 79 + private val searchCommentsAdapter: BaseRecyclerAdapter by lazy { 80 + BaseRecyclerAdapter( 81 + createLoaderAdapterDelegate(), 82 + createChangeRecordCommentFieldAdapterDelegate( 83 + afterTextChange = viewModel::onSearchCommentChange, 84 + onSearchClick = viewModel::onSearchCommentClick, 85 + ), 86 + createChangeRecordCommentAdapterDelegate(viewModel::onCommentClick), 87 + ) 88 + } 76 89 77 90 fun initUi( 78 91 binding: ChangeRecordCoreLayoutBinding, ··· 103 116 } 104 117 adapter = commentsAdapter 105 118 } 119 + rvChangeRecordSearchComments.apply { 120 + layoutManager = FlexboxLayoutManager(context).apply { 121 + flexDirection = FlexDirection.ROW 122 + justifyContent = JustifyContent.CENTER 123 + flexWrap = FlexWrap.WRAP 124 + } 125 + adapter = searchCommentsAdapter 126 + } 106 127 } 107 128 108 129 fun initUx( ··· 110 131 ) = with(binding) { 111 132 etChangeRecordComment.doAfterTextChanged { viewModel.onCommentChange(it.toString()) } 112 133 btnChangeRecordFavouriteComment.setOnClick(viewModel::onFavouriteCommentClick) 134 + btnChangeRecordSearchComment.setOnClick(viewModel::onSearchCommentClick) 113 135 fieldChangeRecordType.setOnClick(viewModel::onTypeChooserClick) 114 136 fieldChangeRecordCategory.setOnClick(viewModel::onCategoryChooserClick) 115 137 fieldChangeRecordComment.setOnClick(viewModel::onCommentChooserClick) ··· 164 186 lastComments.observe(commentsAdapter::replace) 165 187 comment.observe { updateUi(binding, it) } 166 188 favCommentViewData.observe { setFavCommentState(it, binding) } 189 + searchCommentViewData.observe { setSearchCommentState(it, binding) } 167 190 mergePreview.observe { setMergePreview(it, binding) } 168 191 splitPreview.observe { setSplitPreview(it, binding) } 169 192 adjustPreview.observe { setAdjustPreview(it, binding) } ··· 267 290 ColorStateList.valueOf(data.iconColor) 268 291 ) 269 292 binding.btnChangeRecordFavouriteComment.visible = data.isVisible 293 + } 294 + 295 + private fun setSearchCommentState( 296 + data: ChangeRecordSearchCommentState, 297 + binding: ChangeRecordCoreLayoutBinding, 298 + ) { 299 + if (data.enabled) { 300 + binding.containerChangeRecordCommentField.visible = false 301 + binding.rvChangeRecordSearchComments.visible = true 302 + } else { 303 + binding.containerChangeRecordCommentField.visible = true 304 + binding.rvChangeRecordSearchComments.visible = false 305 + } 306 + searchCommentsAdapter.replaceAsNew(data.items) 270 307 } 271 308 272 309 private fun ChangeRecordPreviewLayoutBinding.setData(data: ChangeRecordPreview) {
-24
features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/viewData/ChangeRecordCommentViewData.kt
··· 1 - package com.example.util.simpletimetracker.feature_change_record.viewData 2 - 3 - import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType 4 - 5 - sealed class ChangeRecordCommentViewData : ViewHolderType { 6 - 7 - abstract val text: String 8 - 9 - override fun getUniqueId(): Long = text.hashCode().toLong() 10 - 11 - data class Last( 12 - override val text: String, 13 - ) : ChangeRecordCommentViewData() { 14 - 15 - override fun isValidType(other: ViewHolderType): Boolean = other is Last 16 - } 17 - 18 - data class Favourite( 19 - override val text: String, 20 - ) : ChangeRecordCommentViewData() { 21 - 22 - override fun isValidType(other: ViewHolderType): Boolean = other is Favourite 23 - } 24 - }
+8
features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/viewData/ChangeRecordSearchCommentState.kt
··· 1 + package com.example.util.simpletimetracker.feature_change_record.viewData 2 + 3 + import com.example.util.simpletimetracker.feature_base_adapter.ViewHolderType 4 + 5 + data class ChangeRecordSearchCommentState( 6 + val enabled: Boolean, 7 + val items: List<ViewHolderType>, 8 + )
+65 -2
features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/viewModel/ChangeRecordBaseViewModel.kt
··· 11 11 import com.example.util.simpletimetracker.core.interactor.RecordTypesViewDataInteractor 12 12 import com.example.util.simpletimetracker.core.repo.ResourceRepo 13 13 import com.example.util.simpletimetracker.core.view.timeAdjustment.TimeAdjustmentView 14 + import com.example.util.simpletimetracker.domain.extension.orFalse 14 15 import com.example.util.simpletimetracker.domain.interactor.FavouriteCommentInteractor 15 16 import com.example.util.simpletimetracker.domain.interactor.PrefsInteractor 16 17 import com.example.util.simpletimetracker.domain.interactor.RecordInteractor ··· 24 25 import com.example.util.simpletimetracker.feature_change_record.interactor.ChangeRecordViewDataInteractor 25 26 import com.example.util.simpletimetracker.feature_change_record.model.TimeAdjustmentState 26 27 import com.example.util.simpletimetracker.feature_change_record.viewData.ChangeRecordChooserState 27 - import com.example.util.simpletimetracker.feature_change_record.viewData.ChangeRecordCommentViewData 28 + import com.example.util.simpletimetracker.feature_change_record.adapter.ChangeRecordCommentViewData 28 29 import com.example.util.simpletimetracker.feature_change_record.viewData.ChangeRecordFavCommentState 30 + import com.example.util.simpletimetracker.feature_change_record.viewData.ChangeRecordSearchCommentState 29 31 import com.example.util.simpletimetracker.navigation.Router 30 32 import com.example.util.simpletimetracker.navigation.params.notification.SnackBarParams 31 33 import com.example.util.simpletimetracker.navigation.params.screen.ChangeRecordTagFromScreen ··· 35 37 import kotlinx.coroutines.delay 36 38 import kotlinx.coroutines.launch 37 39 import java.util.concurrent.TimeUnit 40 + import kotlinx.coroutines.Job 38 41 39 42 abstract class ChangeRecordBaseViewModel( 40 43 private val router: Router, ··· 87 90 previous = ChangeRecordChooserState.State.Closed, 88 91 ) 89 92 ) 93 + val searchCommentViewData: LiveData<ChangeRecordSearchCommentState> by lazy { 94 + return@lazy MutableLiveData<ChangeRecordSearchCommentState>().let { initial -> 95 + viewModelScope.launch { 96 + initial.value = loadSearchCommentViewData(isLoading = false, isEnabled = false) 97 + } 98 + initial 99 + } 100 + } 90 101 val timeAdjustmentState: LiveData<TimeAdjustmentState> = MutableLiveData(TimeAdjustmentState.TIME_STARTED) 91 102 val saveButtonEnabled: LiveData<Boolean> = MutableLiveData(true) 92 103 val keyboardVisibility: LiveData<Boolean> = MutableLiveData(false) ··· 115 126 116 127 private var prevRecord: Record? = null 117 128 private var nextRecord: Record? = null 129 + private var searchComment: String = "" 130 + private var searchLoadJob: Job? = null 118 131 119 132 protected open suspend fun initializePreviewViewData() { 120 133 // Don't wait for the completion. ··· 329 342 } 330 343 } 331 344 345 + fun onSearchCommentChange(search: String) { 346 + val isEnabled = searchCommentViewData.value?.enabled ?: return 347 + 348 + if (search != searchComment && isEnabled) { 349 + searchComment = search 350 + searchLoadJob?.cancel() 351 + searchLoadJob = viewModelScope.launch { 352 + updateSearchCommentViewData(isLoading = true, isEnabled = true) 353 + updateSearchCommentViewData(isLoading = false, isEnabled = true) 354 + } 355 + } 356 + } 357 + 332 358 fun onFavouriteCommentClick() { 333 359 if (newComment.isEmpty()) return 334 360 ··· 341 367 } 342 368 updateLastCommentsViewData() 343 369 updateFavCommentViewData() 370 + } 371 + } 372 + 373 + fun onSearchCommentClick() { 374 + val currentlyEnabled = searchCommentViewData.value?.enabled.orFalse() 375 + 376 + keyboardVisibility.set(false) 377 + viewModelScope.launch { 378 + updateSearchCommentViewData( 379 + isEnabled = !currentlyEnabled, 380 + isLoading = false 381 + ) 344 382 } 345 383 } 346 384 ··· 450 488 } 451 489 452 490 // Show keyboard on comment chooser opened, hide otherwise. 453 - keyboardVisibility.set(newState is ChangeRecordChooserState.State.Comment) 491 + val showKeyboard = newState is ChangeRecordChooserState.State.Comment && 492 + !searchCommentViewData.value?.enabled.orFalse() 493 + keyboardVisibility.set(showKeyboard) 494 + 454 495 chooserState.set( 455 496 ChangeRecordChooserState( 456 497 current = newState, ··· 600 641 601 642 private suspend fun loadFavCommentViewData(): ChangeRecordFavCommentState { 602 643 return changeRecordViewDataInteractor.getFavCommentViewData(newComment) 644 + } 645 + 646 + private suspend fun updateSearchCommentViewData( 647 + isLoading: Boolean, 648 + isEnabled: Boolean, 649 + ) { 650 + val data = loadSearchCommentViewData( 651 + isLoading = isLoading, 652 + isEnabled = isEnabled 653 + ) 654 + searchCommentViewData.set(data) 655 + } 656 + 657 + private suspend fun loadSearchCommentViewData( 658 + isLoading: Boolean, 659 + isEnabled: Boolean, 660 + ): ChangeRecordSearchCommentState { 661 + return changeRecordViewDataInteractor.getSearchCommentViewData( 662 + isEnabled = isEnabled, 663 + isLoading = isLoading, 664 + search = searchComment, 665 + ) 603 666 } 604 667 605 668 companion object {