anytype-kotlin-wild/app/src/main/java/com/anytypeio/anytype/ui/relations/add/BaseAddOptionsRelationFragment.kt
Evgenii Kozlov 36fe52e5ad
DROID-607 Relations & types and options | Refactoring | Everything-is-an-object refactoring (#2720)
* 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)
2022-11-24 18:11:19 +03:00

216 lines
8.4 KiB
Kotlin

package com.anytypeio.anytype.ui.relations.add
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.EditText
import androidx.core.view.updatePadding
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.anytypeio.anytype.R
import com.anytypeio.anytype.core_ui.features.sets.RelationValueAdapter
import com.anytypeio.anytype.core_ui.reactive.clicks
import com.anytypeio.anytype.core_ui.reactive.focusChanges
import com.anytypeio.anytype.core_ui.reactive.textChanges
import com.anytypeio.anytype.core_utils.ext.arg
import com.anytypeio.anytype.core_utils.ext.argString
import com.anytypeio.anytype.core_utils.ext.dimen
import com.anytypeio.anytype.core_utils.ext.drawable
import com.anytypeio.anytype.core_utils.ext.gone
import com.anytypeio.anytype.core_utils.ext.hideKeyboard
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.ui.BaseDialogFragment
import com.anytypeio.anytype.databinding.AddOptionRelationFragmentBinding
import com.anytypeio.anytype.presentation.relations.RelationValueView
import com.anytypeio.anytype.presentation.relations.add.BaseAddOptionsRelationViewModel
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
abstract class BaseAddOptionsRelationFragment : BaseDialogFragment<AddOptionRelationFragmentBinding>() {
private val behavior get() = BottomSheetBehavior.from(binding.sheet)
val ctx get() = argString(CTX_KEY)
val relationId get() = argString(RELATION_ID)
val relationKey get() = argString(RELATION_KEY)
val target get() = argString(TARGET_KEY)
val flow get() = arg<Int>(FLOW_KEY)
val dataview get() = argString(DATAVIEW_KEY)
val viewer get() = argString(VIEWER_KEY)
private lateinit var searchRelationInput: EditText
private lateinit var clearSearchText: View
abstract val vm: BaseAddOptionsRelationViewModel
private val editCellTagAdapter by lazy {
RelationValueAdapter(
onCreateOptionClicked = { name -> onCreateOptionClicked(name) },
onTagClicked = { tag -> vm.onTagClicked(tag) },
onStatusClicked = { status -> onStatusClicked(status) },
onRemoveTagClicked = {},
onRemoveStatusClicked = {},
onObjectClicked = {},
onRemoveObjectClicked = {},
onFileClicked = {},
onRemoveFileClicked = {}
)
}
abstract fun onStatusClicked(status: RelationValueView.Option.Status)
abstract fun onCreateOptionClicked(name: String)
abstract fun onAddButtonClicked()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return super.onCreateView(inflater, container, savedInstanceState).apply {
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.recycler.apply {
layoutManager = LinearLayoutManager(context)
adapter = editCellTagAdapter
addItemDecoration(
DividerItemDecoration(context, DividerItemDecoration.VERTICAL).apply {
setDrawable(drawable(R.drawable.divider_relations))
}
)
}
searchRelationInput = binding.searchBar.root.findViewById(R.id.filterInputField)
clearSearchText = binding.searchBar.root.findViewById(R.id.clearSearchText)
clearSearchText.setOnClickListener {
searchRelationInput.setText("")
clearSearchText.invisible()
}
with(lifecycleScope) {
subscribe(view.clicks()) { dismiss() }
subscribe(binding.btnAdd.clicks()) { onAddButtonClicked() }
subscribe(searchRelationInput.textChanges()) {
if (it.isEmpty()) clearSearchText.invisible() else clearSearchText.visible()
vm.onFilterInputChanged(it.toString())
}
subscribe(searchRelationInput.focusChanges()) { hasFocus ->
if (hasFocus) behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
}
behavior.apply {
skipCollapsed = true
addBottomSheetCallback(
object : BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) dismiss()
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {
if (vm.isMultiple.value) {
if (slideOffset < 0)
binding.btnAddContainer.gone()
else
binding.btnAddContainer.visible()
}
}
}
)
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
with(lifecycleScope) {
subscribe(vm.ui) { editCellTagAdapter.update(it) }
subscribe(vm.counter) { binding.tvSelectionCounter.text = it.toString() }
subscribe(vm.isAddButtonVisible) { isVisible ->
if (!isVisible) binding.btnAddContainer.gone() else binding.btnAddContainer.visible()
}
subscribe(vm.isDismissed) { isDismissed ->
if (isDismissed) {
proceedWithExiting(dismissParent = false)
}
}
subscribe(vm.isParentDismissed) { isParentDismissed ->
if (isParentDismissed) {
proceedWithExiting(dismissParent = true)
}
}
subscribe(vm.isMultiple) { isMultiple ->
if (isMultiple) {
binding.recycler.updatePadding(
bottom = dimen(R.dimen.multiple_option_value_bottom_list_margin)
)
searchRelationInput.setHint(R.string.choose_options)
} else {
binding.recycler.updatePadding(
bottom = dimen(R.dimen.single_option_value_bottom_list_margin)
)
searchRelationInput.setHint(R.string.choose_option)
}
}
}
}
open fun proceedWithExiting(dismissParent: Boolean = false) {
searchRelationInput.apply {
clearFocus()
hideKeyboard()
}
if (dismissParent) {
(parentFragment as? BottomSheetDialogFragment)?.dismiss()
} else {
dismiss()
}
}
override fun onStart() {
super.onStart()
setupAppearance()
vm.onStart(
target = target,
relationKey = relationKey
)
}
override fun onStop() {
super.onStop()
vm.onStop()
}
private fun setupAppearance() {
dialog?.window?.apply {
setGravity(Gravity.BOTTOM)
setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
setBackgroundDrawableResource(android.R.color.transparent)
setWindowAnimations(R.style.DefaultBottomDialogAnimation)
}
}
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?
): AddOptionRelationFragmentBinding = AddOptionRelationFragmentBinding.inflate(
inflater, container, false
)
companion object {
const val CTX_KEY = "arg.add-object-relation-value.ctx"
const val RELATION_ID = "arg.add-object-relation-value.relation.id"
const val RELATION_KEY = "arg.add-object-relation-value.relation.key"
const val TARGET_KEY = "arg.add-object-relation-value.target"
const val FLOW_KEY = "arg.add-object-relation-value.flow"
const val DATAVIEW_KEY = "arg.add-object-relation-value.data-view"
const val VIEWER_KEY = "arg.add-object-relation-value.viewer"
}
}