* 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)
224 lines
8.1 KiB
Kotlin
224 lines
8.1 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.os.bundleOf
|
|
import androidx.fragment.app.viewModels
|
|
import androidx.lifecycle.lifecycleScope
|
|
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.features.relations.RelationObjectValueAdapter
|
|
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.argString
|
|
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.BaseDialogFragment
|
|
import com.anytypeio.anytype.databinding.FragmentRelationObjectValueAddBinding
|
|
import com.anytypeio.anytype.di.common.componentManager
|
|
import com.anytypeio.anytype.presentation.relations.add.AddObjectRelationViewModel
|
|
import com.anytypeio.anytype.presentation.relations.add.ObjectValueAddCommand
|
|
import com.anytypeio.anytype.presentation.relations.add.ObjectValueAddView
|
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
import javax.inject.Inject
|
|
|
|
class AddObjectRelationFragment : BaseDialogFragment<FragmentRelationObjectValueAddBinding>() {
|
|
|
|
private val behavior get() = BottomSheetBehavior.from(binding.sheet)
|
|
|
|
@Inject
|
|
lateinit var factory: AddObjectRelationViewModel.Factory
|
|
val vm: AddObjectRelationViewModel by viewModels { factory }
|
|
|
|
private val ctx get() = argString(CONTEXT_ID)
|
|
private val objectId get() = argString(OBJECT_ID)
|
|
private val relationId get() = argString(RELATION_ID)
|
|
private val relationKey get() = argString(RELATION_KEY)
|
|
private val types get() = arg<List<String>>(TARGET_TYPES)
|
|
private val flow get() = arg<Int>(FLOW_KEY)
|
|
|
|
private lateinit var searchRelationInput: EditText
|
|
private lateinit var clearSearchText: View
|
|
|
|
private val adapter by lazy {
|
|
RelationObjectValueAdapter(
|
|
onObjectClick = { objectId -> vm.onObjectClicked(objectId) }
|
|
)
|
|
}
|
|
|
|
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)
|
|
with(lifecycleScope) {
|
|
subscribe(view.clicks()) { dismiss() }
|
|
}
|
|
binding.rvObjects.layoutManager = LinearLayoutManager(requireContext())
|
|
binding.rvObjects.adapter = adapter
|
|
binding.btnBottomAction.setOnClickListener { vm.onActionButtonClicked() }
|
|
setupBottomSheet()
|
|
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()
|
|
}
|
|
}
|
|
|
|
private fun setupBottomSheet() {
|
|
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 (binding.btnAddContainer == null) return
|
|
if (slideOffset < 0)
|
|
binding.btnAddContainer.gone()
|
|
else
|
|
binding.btnAddContainer.visible()
|
|
}
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
override fun onStart() {
|
|
jobs += lifecycleScope.subscribe(vm.viewsFiltered) { observeState(it) }
|
|
jobs += lifecycleScope.subscribe(vm.commands) { observeCommands(it) }
|
|
jobs += lifecycleScope.subscribe(searchRelationInput.textChanges())
|
|
{
|
|
if (it.isEmpty()) clearSearchText.invisible() else clearSearchText.visible()
|
|
vm.onFilterTextChanged(it.toString())
|
|
}
|
|
super.onStart()
|
|
setupAppearance()
|
|
vm.onStart(objectId = objectId, relationKey = relationKey, targetTypes = types)
|
|
}
|
|
|
|
override fun onStop() {
|
|
super.onStop()
|
|
vm.onStop()
|
|
}
|
|
|
|
private fun observeState(state: ObjectValueAddView) {
|
|
adapter.update(state.objects)
|
|
binding.tvObjectsCount.text = state.count
|
|
}
|
|
|
|
private fun observeCommands(command: ObjectValueAddCommand) {
|
|
when (command) {
|
|
is ObjectValueAddCommand.DispatchResult -> {
|
|
dispatchResultAndDismiss(command.ids)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun dispatchResultAndDismiss(ids: List<Id>) {
|
|
withParent<ObjectValueAddReceiver> {
|
|
onObjectValueChanged(
|
|
ctx = ctx,
|
|
objectId = objectId,
|
|
relationKey = relationKey,
|
|
ids = ids
|
|
)
|
|
}
|
|
dismiss()
|
|
}
|
|
|
|
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 injectDependencies() {
|
|
if (flow == FLOW_DEFAULT) {
|
|
componentManager().addObjectRelationObjectValueComponent.get(ctx).inject(this)
|
|
} else {
|
|
componentManager().addObjectSetObjectRelationObjectValueComponent.get(ctx).inject(this)
|
|
}
|
|
}
|
|
|
|
override fun releaseDependencies() {
|
|
if (flow == FLOW_DEFAULT) {
|
|
componentManager().addObjectRelationObjectValueComponent.release(ctx)
|
|
} else {
|
|
componentManager().addObjectSetObjectRelationObjectValueComponent.release(ctx)
|
|
}
|
|
}
|
|
|
|
override fun inflateBinding(
|
|
inflater: LayoutInflater,
|
|
container: ViewGroup?
|
|
): FragmentRelationObjectValueAddBinding = FragmentRelationObjectValueAddBinding.inflate(
|
|
inflater, container, false
|
|
)
|
|
|
|
companion object {
|
|
|
|
fun new(
|
|
ctx: Id,
|
|
objectId: Id,
|
|
relationId: Id,
|
|
relationKey: Key,
|
|
types: List<Id>,
|
|
flow: Int = FLOW_DEFAULT
|
|
) = AddObjectRelationFragment().apply {
|
|
arguments = bundleOf(
|
|
CONTEXT_ID to ctx,
|
|
OBJECT_ID to objectId,
|
|
RELATION_ID to relationId,
|
|
RELATION_KEY to relationKey,
|
|
TARGET_TYPES to types,
|
|
FLOW_KEY to flow
|
|
)
|
|
}
|
|
|
|
const val CONTEXT_ID = "arg.relation.add.object.context"
|
|
const val RELATION_ID = "arg.relation.add.object.relation.id"
|
|
const val RELATION_KEY = "arg.relation.add.object.relation.key"
|
|
const val OBJECT_ID = "arg.relation.add.object.object.id"
|
|
const val TARGET_TYPES = "arg.relation.add.object.target_types"
|
|
const val FLOW_KEY = "arg.relation.add.object.flow"
|
|
const val FLOW_DEFAULT = 0
|
|
const val FLOW_DATAVIEW = 1
|
|
}
|
|
|
|
interface ObjectValueAddReceiver {
|
|
fun onObjectValueChanged(
|
|
ctx: Id,
|
|
objectId: Id,
|
|
relationKey: Key,
|
|
ids: List<Id>
|
|
)
|
|
}
|
|
} |