* DROID-439 App | Relations refactoring, use SearchObjects for object types (#2592) * DROID-446 Objects | Enhancement | Store relation links and process its updates (#2597) * DROID-456 Tech | Remove deprecated API for creating object types (#2601) * DROID-455 Object types | Enhancement Get object type list from ObjectSearch on Global search screen (#2602) * DROID-459 Sets | Refactoring | Use relations links instead of relations for building search params to get data view data (#2603) * DROID-458 Objects | Refactoring | Integrate new api for creating objets (#2604) * DROID-464 Relations | Refactoring | New API for creating a relation from scratch - for data view or for an object (#2605) * DROID-467 Relations | Refactoring | New API for creating options - for tags and statuses (#2607) * DROID-470 Relations | Refactoring | New API for removing any relation from an object or from a data view (#2608) * DROID-460 Tech | Object relations list (#2610) * DROID-486 Sets | Refactoring | Displaying and controlling visibility of data view relations (#2611) * DROID-500 Relations | Refactoring | Extend API of ObjectStore to be able to get a relation by its id (#2619) * DROID-459 Sets | Fix | Get relations from store by id and not by key (#2618) * DROID-489 Tech | Relations as object, add relationKey to relation connected screens (#2622) * DROID-490 Sets | Refactoring | Displaying relation values for current object in bottom sheet cells (#2629) * DROID-505 Relations | Refactoring | New interface for relations store (#2633) * DROID-509 Relations | Refactoring | Bind new relations store with subscription container (#2635) * DROID-507 Tech | MW , migration + relation links (#2636) * DROID-507 Tech | MW , migration + relation links, fixes (#2637) * DROID-517 Sets | Fix | Provide correct keys for data view search-and-subscribe query (#2641) * DROID-409 Relations | Refactoring | Use relation key instead of id when creating new relation (#2642) * DROID-521 Sets & Objects | Refactoring | Add relation to a data view or to an object from existing relations (#2644) * DROID-522 Relations | Refactoring | Add objects to relations with object format (#2645) * DROID-523 Object types | Refactoring | Implement global store for object types (#2646) * DROID-527 Object types | Refactoring | Integrate global store for object types (#2647) * DROID-531 Relations | Refactoring | Parse tag and status relations values (#2649) * DROID-535 Tech | Integrate new MW lib with migration fixes (#2653) * DROID-535 Tech | MW integration fixes (#2660) * DROID-559 Relations | Refactoring | Parse tag and status values in editor (#2662) * DROID-560 Relations | Refactoring | Integrate new lib with fixes (#2663) * DROID-561 Relations | Refactoring | Parsing tag and status values in dv (#2665) * DROID-562 Dashboard | Refactoring | Use store of object types as object type provider for favorites tab on dashboard (#2667) * DROID-567 Relations | Refactoring | Suggest available options to populate a relation (#2671) * DROID-604 Relations | Refactoring | Use details from Object.CreateRelation.Response to populate relation store (#2705) * DROID-603 Relations | Refactoring | Creating relation options + Deleting relation from object (#2706) * DROID-619 Relations | Refactoring | Migrate data view sorts and filters to the new relation-as-object paradigm (#2711) * DROID-622 Relations | Tech | Update MW to 0.24.0-rc1 (#2714) * DROID-598 Sets | Refactoring | Provide relation format for date filters (#2715) * DROID-625 Protocol | Enhancement | Integrate v0.24.0-rc2 (#2718)
218 lines
8.8 KiB
Kotlin
218 lines
8.8 KiB
Kotlin
package com.anytypeio.anytype.ui.sets.modals.filter
|
|
|
|
import android.os.Bundle
|
|
import android.view.LayoutInflater
|
|
import android.view.View
|
|
import android.view.ViewGroup
|
|
import android.widget.EditText
|
|
import androidx.core.os.bundleOf
|
|
import androidx.fragment.app.viewModels
|
|
import androidx.lifecycle.lifecycleScope
|
|
import androidx.recyclerview.widget.DividerItemDecoration
|
|
import androidx.recyclerview.widget.LinearLayoutManager
|
|
import com.anytypeio.anytype.R
|
|
import com.anytypeio.anytype.core_models.Id
|
|
import com.anytypeio.anytype.core_models.Key
|
|
import com.anytypeio.anytype.core_ui.extensions.relationIcon
|
|
import com.anytypeio.anytype.core_ui.features.sets.CreateFilterAdapter
|
|
import com.anytypeio.anytype.core_ui.reactive.clicks
|
|
import com.anytypeio.anytype.core_ui.reactive.textChanges
|
|
import com.anytypeio.anytype.core_utils.ext.arg
|
|
import com.anytypeio.anytype.core_utils.ext.drawable
|
|
import com.anytypeio.anytype.core_utils.ext.gone
|
|
import com.anytypeio.anytype.core_utils.ext.invisible
|
|
import com.anytypeio.anytype.core_utils.ext.subscribe
|
|
import com.anytypeio.anytype.core_utils.ext.visible
|
|
import com.anytypeio.anytype.core_utils.ext.withParent
|
|
import com.anytypeio.anytype.core_utils.ui.BaseFragment
|
|
import com.anytypeio.anytype.databinding.FragmentCreateOrUpdateFilterBinding
|
|
import com.anytypeio.anytype.di.common.componentManager
|
|
import com.anytypeio.anytype.presentation.sets.filter.FilterViewModel
|
|
import com.anytypeio.anytype.presentation.sets.model.Viewer
|
|
import com.anytypeio.anytype.ui.relations.RelationTextValueFragment
|
|
import com.anytypeio.anytype.ui.sets.modals.DatePickerFragment
|
|
import com.anytypeio.anytype.ui.sets.modals.DatePickerFragment.DatePickerReceiver
|
|
import com.anytypeio.anytype.ui.sets.modals.PickFilterConditionFragment
|
|
import com.anytypeio.anytype.ui.sets.modals.filter.CreateFilterFromInputFieldValueFragment.Companion.FILTER_INDEX_EMPTY
|
|
import kotlinx.coroutines.flow.combine
|
|
import kotlinx.coroutines.flow.filterNotNull
|
|
import kotlinx.coroutines.flow.onStart
|
|
import javax.inject.Inject
|
|
|
|
open class CreateFilterFromSelectedValueFragment :
|
|
BaseFragment<FragmentCreateOrUpdateFilterBinding>(R.layout.fragment_create_or_update_filter),
|
|
UpdateConditionActionReceiver,
|
|
DatePickerReceiver,
|
|
RelationTextValueFragment.TextValueEditReceiver {
|
|
|
|
private val ctx: String get() = arg(CTX_KEY)
|
|
private val relation: String get() = arg(RELATION_KEY)
|
|
|
|
private val helper = FilterHelper()
|
|
|
|
private lateinit var searchRelationInput: EditText
|
|
lateinit var clearSearchText: View
|
|
|
|
@Inject
|
|
lateinit var factory: FilterViewModel.Factory
|
|
|
|
private val vm: FilterViewModel by viewModels { factory }
|
|
|
|
private val createFilterAdapter by lazy {
|
|
CreateFilterAdapter(
|
|
onItemClicked = vm::onFilterItemClicked
|
|
)
|
|
}
|
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
super.onViewCreated(view, savedInstanceState)
|
|
binding.btnBottomAction.setText(R.string.create)
|
|
searchRelationInput = binding.searchBar.root.findViewById(R.id.filterInputField)
|
|
searchRelationInput.apply {
|
|
hint = getString(R.string.choose_options)
|
|
}
|
|
clearSearchText = binding.searchBar.root.findViewById(R.id.clearSearchText)
|
|
clearSearchText.setOnClickListener {
|
|
searchRelationInput.setText("")
|
|
clearSearchText.invisible()
|
|
}
|
|
binding.rvViewerFilterRecycler.apply {
|
|
layoutManager = LinearLayoutManager(context)
|
|
adapter = createFilterAdapter
|
|
addItemDecoration(
|
|
DividerItemDecoration(context, DividerItemDecoration.VERTICAL).apply {
|
|
setDrawable(drawable(R.drawable.divider_filter_list))
|
|
}
|
|
)
|
|
}
|
|
with(lifecycleScope) {
|
|
subscribe(binding.tvFilterCondition.clicks()) {
|
|
vm.onConditionClicked()
|
|
}
|
|
subscribe(binding.btnBottomAction.clicks()) {
|
|
vm.onCreateFilterFromSelectedValueClicked(ctx = ctx, relation = relation)
|
|
}
|
|
subscribe(vm.relationState.filterNotNull()) {
|
|
binding.tvRelationName.text = it.title
|
|
binding.ivRelationIcon.setImageResource(it.format.relationIcon(true))
|
|
}
|
|
subscribe(vm.optionCountState) { binding.tvOptionCount.text = it.toString() }
|
|
subscribe(vm.isCompleted) { isCompleted ->
|
|
if (isCompleted) withParent<CreateFilterFlow> { onFilterCreated() }
|
|
}
|
|
subscribe(vm.conditionState) {
|
|
binding.tvFilterCondition.text = it?.condition?.title
|
|
}
|
|
subscribe(searchRelationInput.textChanges()) {
|
|
if (it.isEmpty()) {
|
|
clearSearchText.invisible()
|
|
} else {
|
|
clearSearchText.visible()
|
|
}
|
|
}
|
|
val queries = searchRelationInput.textChanges()
|
|
.onStart { emit(searchRelationInput.text.toString()) }
|
|
val views =
|
|
vm.filterValueListState.combine(queries) { views, query ->
|
|
if (views.isEmpty()) {
|
|
views
|
|
} else {
|
|
views.filter { it.text.contains(query, true) }
|
|
}
|
|
}
|
|
subscribe(views) { createFilterAdapter.update(it) }
|
|
subscribe(vm.commands) { observeCommands(it) }
|
|
}
|
|
}
|
|
|
|
override fun onTextValueChanged(ctx: Id, text: String, objectId: Id, relationKey: Key) {}
|
|
|
|
override fun onNumberValueChanged(ctx: Id, number: Double?, objectId: Id, relationKey: Key) {
|
|
helper.handleNumberValueChanged(this, number, vm)
|
|
}
|
|
|
|
override fun onStart() {
|
|
super.onStart()
|
|
vm.onStart(relationKey = relation, filterIndex = FILTER_INDEX_EMPTY)
|
|
}
|
|
|
|
override fun onStop() {
|
|
super.onStop()
|
|
vm.onStop()
|
|
}
|
|
|
|
private fun observeCommands(commands: FilterViewModel.Commands) {
|
|
when (commands) {
|
|
is FilterViewModel.Commands.OpenDatePicker -> {
|
|
DatePickerFragment.new(commands.timeInSeconds)
|
|
.show(childFragmentManager, null)
|
|
}
|
|
is FilterViewModel.Commands.OpenConditionPicker -> {
|
|
PickFilterConditionFragment.new(
|
|
ctx = ctx,
|
|
mode = PickFilterConditionFragment.MODE_CREATE,
|
|
type = commands.type,
|
|
index = commands.index
|
|
).show(childFragmentManager, null)
|
|
}
|
|
FilterViewModel.Commands.ShowCount -> binding.tvOptionCount.visible()
|
|
FilterViewModel.Commands.HideCount -> binding.tvOptionCount.gone()
|
|
FilterViewModel.Commands.ShowSearchbar -> binding.searchBar.root.visible()
|
|
FilterViewModel.Commands.HideSearchbar -> binding.searchBar.root.gone()
|
|
FilterViewModel.Commands.DateDivider -> setDivider(R.drawable.divider_relation_date)
|
|
FilterViewModel.Commands.ObjectDivider -> setDivider(R.drawable.divider_relation_object)
|
|
FilterViewModel.Commands.TagDivider -> setDivider(R.drawable.divider_relation_tag)
|
|
FilterViewModel.Commands.ShowInput -> {}
|
|
FilterViewModel.Commands.HideInput -> {}
|
|
is FilterViewModel.Commands.OpenNumberPicker -> {
|
|
helper.handleOpenNumberPicker(
|
|
fragment = this,
|
|
command = commands,
|
|
ctx = ctx
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun setDivider(divider: Int) {
|
|
binding.rvViewerFilterRecycler.apply {
|
|
addItemDecoration(
|
|
DividerItemDecoration(context, DividerItemDecoration.VERTICAL).apply {
|
|
setDrawable(drawable(divider))
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
override fun update(condition: Viewer.Filter.Condition) {
|
|
vm.onConditionUpdate(condition)
|
|
}
|
|
|
|
override fun onPickDate(timeInSeconds: Long) {
|
|
vm.onExactDayPicked(timeInSeconds)
|
|
}
|
|
|
|
override fun injectDependencies() {
|
|
componentManager().createFilterComponent.get(ctx).inject(this)
|
|
}
|
|
|
|
override fun releaseDependencies() {
|
|
componentManager().createFilterComponent.release(ctx)
|
|
}
|
|
|
|
override fun inflateBinding(
|
|
inflater: LayoutInflater,
|
|
container: ViewGroup?
|
|
): FragmentCreateOrUpdateFilterBinding = FragmentCreateOrUpdateFilterBinding.inflate(
|
|
inflater, container, false
|
|
)
|
|
|
|
companion object {
|
|
fun new(ctx: Id, relation: Id): CreateFilterFromSelectedValueFragment = CreateFilterFromSelectedValueFragment().apply {
|
|
arguments = bundleOf(CTX_KEY to ctx, RELATION_KEY to relation)
|
|
}
|
|
|
|
const val CTX_KEY = "arg.create-filter-relation.ctx"
|
|
const val RELATION_KEY = "arg.create-filter-relation.relation"
|
|
}
|
|
} |