1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

DROID-326 Sets | Enhancement | Relation list should be provided not from data view, but from object itself (#3035)

This commit is contained in:
Evgenii Kozlov 2023-03-22 16:30:49 +01:00 committed by GitHub
parent 1abf1db680
commit c523a65b14
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 158 additions and 29 deletions

View file

@ -59,7 +59,6 @@ import com.anytypeio.anytype.di.feature.TextBlockIconPickerModule
import com.anytypeio.anytype.di.feature.ViewerFilterModule
import com.anytypeio.anytype.di.feature.ViewerSortModule
import com.anytypeio.anytype.di.feature.auth.DaggerDeletedAccountComponent
import com.anytypeio.anytype.di.feature.auth.DeletedAccountModule
import com.anytypeio.anytype.di.feature.cover.UnsplashModule
import com.anytypeio.anytype.di.feature.home.DaggerHomeScreenComponent
import com.anytypeio.anytype.di.feature.library.DaggerLibraryComponent
@ -675,6 +674,14 @@ class ComponentManager(
.build()
}
val relationAddToObjectSetComponent = DependentComponentMap { ctx ->
objectSetComponent
.get(ctx)
.relationAddToObjectComponent()
.module(RelationAddToObjectModule)
.build()
}
val relationAddToDataViewComponent = DependentComponentMap { ctx ->
objectSetComponent
.get(ctx)
@ -691,6 +698,14 @@ class ComponentManager(
.build()
}
val relationCreateFromScratchForObjectSetComponent = DependentComponentMap { ctx ->
objectSetComponent
.get(ctx)
.relationCreateFromScratchForObjectComponent()
.module(RelationCreateFromScratchForObjectModule)
.build()
}
val relationFormatPickerObjectComponent = DependentComponentMap { ctx ->
relationCreateFromScratchForObjectComponent
.get(ctx)

View file

@ -7,7 +7,9 @@ import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
import com.anytypeio.anytype.di.feature.cover.UnsplashSubComponent
import com.anytypeio.anytype.di.feature.relations.RelationAddToDataViewSubComponent
import com.anytypeio.anytype.di.feature.relations.RelationAddToObjectSubComponent
import com.anytypeio.anytype.di.feature.relations.RelationCreateFromScratchForDataViewSubComponent
import com.anytypeio.anytype.di.feature.relations.RelationCreateFromScratchForObjectSubComponent
import com.anytypeio.anytype.di.feature.sets.CreateFilterSubComponent
import com.anytypeio.anytype.di.feature.sets.ModifyFilterSubComponent
import com.anytypeio.anytype.di.feature.sets.SelectFilterRelationSubComponent
@ -38,6 +40,7 @@ import com.anytypeio.anytype.domain.objects.options.GetOptions
import com.anytypeio.anytype.domain.page.CloseBlock
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.relations.AddFileToObject
import com.anytypeio.anytype.domain.relations.AddRelationToObject
import com.anytypeio.anytype.domain.relations.DeleteRelationFromDataView
import com.anytypeio.anytype.domain.search.CancelSearchSubscription
import com.anytypeio.anytype.domain.search.DataViewSubscriptionContainer
@ -120,6 +123,8 @@ interface ObjectSetSubComponent {
fun objectUnsplashComponent(): UnsplashSubComponent.Builder
fun objectRelationListComponent(): ObjectRelationListComponent.Builder
fun relationAddToObjectComponent(): RelationAddToObjectSubComponent.Builder
fun relationCreateFromScratchForObjectComponent(): RelationCreateFromScratchForObjectSubComponent.Builder
}
@Module(
@ -525,10 +530,15 @@ object ObjectSetModule {
@PerScreen
fun dataViewRelationListProvider(
objectStateFlow: MutableStateFlow<ObjectState>
) : RelationListProvider = RelationListProvider.DataViewRelationListProvider(
) : RelationListProvider = RelationListProvider.ObjectSetRelationListProvider(
objectStates = objectStateFlow
)
@JvmStatic
@Provides
@PerScreen
fun provideAddRelationToObject(repo: BlockRepository) = AddRelationToObject(repo)
@Module
interface Bindings {

View file

@ -102,7 +102,10 @@ open class ObjectRelationListFragment : BaseBottomSheetFragment<FragmentRelation
}
binding.btnPlus.setOnClickListener {
if (!isLocked) {
RelationAddToObjectFragment.new(ctx).showChildFragment()
RelationAddToObjectFragment.new(
ctx = ctx,
isSetOrCollection = isDataViewFLow
).showChildFragment()
} else {
toast(getString(R.string.unlock_your_object_to_add_new_relation))
}

View file

@ -143,6 +143,7 @@ abstract class RelationAddBaseFragment :
class RelationAddToObjectFragment : RelationAddBaseFragment() {
override val ctx get() = arg<Id>(CTX_KEY)
private val isSetOrCollection get() = arg<Boolean>(IS_SET_OR_COLLECTION_KEY)
@Inject
lateinit var factory: RelationAddToObjectViewModel.Factory
@ -160,22 +161,40 @@ class RelationAddToObjectFragment : RelationAddBaseFragment() {
override fun onCreateFromScratchClicked() {
val fr = RelationCreateFromScratchForObjectFragment.new(
ctx = ctx,
query = createFromScratchAdapter.query
query = createFromScratchAdapter.query,
isSetOrCollection = isSetOrCollection
)
fr.showChildFragment()
}
override fun injectDependencies() {
componentManager().relationAddToObjectComponent.get(ctx).inject(this)
if (isSetOrCollection) {
componentManager().relationAddToObjectSetComponent.get(ctx).inject(this)
} else {
componentManager().relationAddToObjectComponent.get(ctx).inject(this)
}
}
override fun releaseDependencies() {
componentManager().relationAddToObjectComponent.release(ctx)
if (isSetOrCollection) {
componentManager().relationAddToObjectSetComponent.release(ctx)
} else {
componentManager().relationAddToObjectComponent.release(ctx)
}
}
companion object {
fun new(ctx: Id) = RelationAddToObjectFragment().apply {
arguments = bundleOf(CTX_KEY to ctx)
private const val IS_SET_OR_COLLECTION_KEY = "arg.relation-add-to-object.is-set-or-collection"
fun new(
ctx: Id,
isSetOrCollection: Boolean = true
) = RelationAddToObjectFragment().apply {
arguments = bundleOf(
CTX_KEY to ctx,
IS_SET_OR_COLLECTION_KEY to isSetOrCollection
)
}
}
}

View file

@ -146,6 +146,8 @@ abstract class RelationCreateFromScratchBaseFragment :
class RelationCreateFromScratchForObjectFragment : RelationCreateFromScratchBaseFragment() {
private val isSetOrCollection : Boolean get() = arg(IS_SET_OR_COLLECTION_KEY)
@Inject
lateinit var factory: RelationCreateFromScratchForObjectViewModel.Factory
override val vm: RelationCreateFromScratchForObjectViewModel by viewModels { factory }
@ -175,16 +177,35 @@ class RelationCreateFromScratchForObjectFragment : RelationCreateFromScratchBase
}
override fun injectDependencies() {
componentManager().relationCreateFromScratchForObjectComponent.get(ctx).inject(this)
if (isSetOrCollection) {
componentManager().relationCreateFromScratchForObjectSetComponent.get(ctx).inject(this)
} else {
componentManager().relationCreateFromScratchForObjectComponent.get(ctx).inject(this)
}
}
override fun releaseDependencies() {
componentManager().relationCreateFromScratchForObjectComponent.release(ctx)
if (isSetOrCollection) {
componentManager().relationCreateFromScratchForObjectSetComponent.release(ctx)
} else {
componentManager().relationCreateFromScratchForObjectComponent.release(ctx)
}
}
companion object {
fun new(ctx: Id, query: String) = RelationCreateFromScratchForObjectFragment().apply {
arguments = bundleOf(CTX_KEY to ctx, QUERY_KEY to query)
private const val IS_SET_OR_COLLECTION_KEY = "arg.relation-create-from-scratch.is-set-or-collection"
fun new(
ctx: Id,
query: String,
isSetOrCollection: Boolean = false
) = RelationCreateFromScratchForObjectFragment().apply {
arguments = bundleOf(
CTX_KEY to ctx,
QUERY_KEY to query,
IS_SET_OR_COLLECTION_KEY to isSetOrCollection
)
}
fun args(ctx: Id, query: String) = bundleOf(CTX_KEY to ctx, QUERY_KEY to query)

View file

@ -173,7 +173,7 @@ class DocumentRelationAdapter(
if (payload.isModeChanged) {
val item = items[position]
check(item is RelationListViewModel.Model.Item)
holder.setIsRemovable(item.isRemoveable)
holder.setIsRemovable(item.isRemovable)
} else {
super.onBindViewHolder(holder, position, payloads)
}
@ -235,7 +235,7 @@ class DocumentRelationAdapter(
if (holder is ListRelationViewHolder) {
check(item is RelationListViewModel.Model.Item)
holder.setIsFeatured(item.view.featured)
holder.setIsRemovable(item.isRemoveable)
holder.setIsRemovable(item.isRemovable)
}
}
@ -289,7 +289,7 @@ class DocumentRelationAdapter(
val oldItem = old[oldItemPosition]
val newItem = new[newItemPosition]
return if (oldItem is RelationListViewModel.Model.Item && newItem is RelationListViewModel.Model.Item) {
if (newItem.isRemoveable != oldItem.isRemoveable)
if (newItem.isRemovable != oldItem.isRemovable)
GranularChange(isModeChanged = true)
else
null

View file

@ -6,7 +6,11 @@
[Main]
- [ObjectSetMenuFragment] showing menu for a Set or Collection
- [ObjectRelationListFragment] displaying list of given object's relations
- [RelationTextValueFragment]
- [ObjectRelationListFragment] displaying list of Relations for this Set or this Collection
- [RelationTextValueFragment] editing Relation from this Data View or from this Set or this Collection
- [RelationAddToObjectFragment] adding a Relation to given Set or Collection
- [RelationAddToDataViewFragment] adding a Relation to the Data View contained in this Set or this Collection
- [RelationCreateFromScratchForObjectFragment] creating a Relation for this Set or this Collection
- [RelationCreateFromScratchForDataViewFragment] creating a Relation for the Data View contained in this Set or this Collection
// TODO

View file

@ -80,7 +80,7 @@ class RelationListViewModel(
).map { view ->
Model.Item(
view = view,
isRemoveable = isPossibleToRemoveRelation(relationKey = view.key)
isRemovable = isPossibleToRemoveRelation(relationKey = view.key)
)
}
}.map { views ->
@ -199,7 +199,7 @@ class RelationListViewModel(
isEditMode.value = !isEditMode.value
views.value = views.value.map { view ->
if (view is Model.Item) {
view.copy(isRemoveable = isPossibleToRemoveRelation(relationKey = view.view.key))
view.copy(isRemovable = isPossibleToRemoveRelation(relationKey = view.view.key))
} else {
view
}
@ -377,7 +377,7 @@ class RelationListViewModel(
data class Item(
val view: ObjectRelationView,
val isRemoveable: Boolean = false
val isRemovable: Boolean = false
) : Model() {
override val identifier: String get() = view.identifier
}

View file

@ -2,7 +2,6 @@ package com.anytypeio.anytype.presentation.relations.providers
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.RelationLink
import com.anytypeio.anytype.core_models.ext.content
import com.anytypeio.anytype.presentation.editor.Editor
import com.anytypeio.anytype.presentation.sets.state.ObjectState
import kotlinx.coroutines.flow.Flow
@ -29,7 +28,7 @@ interface RelationListProvider {
override fun getDetails() = storage.details.current()
}
class DataViewRelationListProvider(
class ObjectSetRelationListProvider(
private val objectStates: StateFlow<ObjectState>
) : RelationListProvider {
@ -51,10 +50,10 @@ interface RelationListProvider {
private fun mapLinks(state: ObjectState) = when (state) {
is ObjectState.DataView.Collection -> {
state.dataViewBlock.content<Block.Content.DataView>().relationLinks
state.objectRelationLinks
}
is ObjectState.DataView.Set -> {
state.dataViewBlock.content<Block.Content.DataView>().relationLinks
state.objectRelationLinks
}
else -> emptyList()
}

View file

@ -7,6 +7,7 @@ import com.anytypeio.anytype.core_models.Event.Command
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.ext.amend
import com.anytypeio.anytype.core_models.ext.remove
import com.anytypeio.anytype.core_models.ext.unset
import com.anytypeio.anytype.core_utils.ext.replace
import com.anytypeio.anytype.presentation.sets.updateFields
@ -56,10 +57,16 @@ class DefaultObjectStateReducer : ObjectStateReducer {
private fun reduce(state: ObjectState, event: Event): Transformation {
val effects = mutableListOf<StateSideEffect>()
val newState = when (event) {
val newState : ObjectState = when (event) {
is Command.ShowObject -> {
handleShowObject(event)
}
is Command.ObjectRelationLinks.Amend -> {
amendObjectRelationLinks(state, event)
}
is Command.ObjectRelationLinks.Remove -> {
removeObjectRelationLinks(state, event)
}
is Command.DataView.SetView -> {
handleSetView(state, event)
}
@ -96,6 +103,7 @@ class DefaultObjectStateReducer : ObjectStateReducer {
is Command.AddBlock -> {
handleAddBlock(state, event)
}
else -> {
Timber.d("Ignoring event: $event")
state
@ -107,6 +115,48 @@ class DefaultObjectStateReducer : ObjectStateReducer {
)
}
private fun removeObjectRelationLinks(
state: ObjectState,
event: Command.ObjectRelationLinks.Remove
) = when (state) {
is ObjectState.DataView.Collection -> {
state.copy(
objectRelationLinks = state.objectRelationLinks.remove(
event.keys
)
)
}
is ObjectState.DataView.Set -> {
state.copy(
objectRelationLinks = state.objectRelationLinks.remove(
event.keys
)
)
}
else -> state
}
private fun amendObjectRelationLinks(
state: ObjectState,
event: Command.ObjectRelationLinks.Amend
) = when (state) {
is ObjectState.DataView.Collection -> {
state.copy(
objectRelationLinks = state.objectRelationLinks.amend(
event.relationLinks
)
)
}
is ObjectState.DataView.Set -> {
state.copy(
objectRelationLinks = state.objectRelationLinks.amend(
event.relationLinks
)
)
}
else -> state
}
//region EVENTS
/**
@ -119,14 +169,16 @@ class DefaultObjectStateReducer : ObjectStateReducer {
blocks = event.blocks,
details = event.details.details,
objectRestrictions = event.objectRestrictions,
dataViewRestrictions = event.dataViewRestrictions
dataViewRestrictions = event.dataViewRestrictions,
objectRelationLinks = event.relationLinks
)
ObjectType.Layout.SET.code -> ObjectState.DataView.Set(
root = event.root,
blocks = event.blocks,
details = event.details.details,
objectRestrictions = event.objectRestrictions,
dataViewRestrictions = event.dataViewRestrictions
dataViewRestrictions = event.dataViewRestrictions,
objectRelationLinks = event.relationLinks
)
else -> {
Timber.e("Wrong layout type: $layout")

View file

@ -4,6 +4,7 @@ import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.DV
import com.anytypeio.anytype.core_models.DVViewer
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.RelationLink
import com.anytypeio.anytype.core_models.restrictions.DataViewRestrictions
import com.anytypeio.anytype.core_models.restrictions.ObjectRestriction
@ -12,12 +13,15 @@ sealed class ObjectState {
abstract val isInitialized: Boolean
sealed class DataView : ObjectState() {
abstract val root: Id
abstract val blocks: List<Block>
abstract val details: Map<Id, Block.Fields>
abstract val objectRestrictions: List<ObjectRestriction>
abstract val dataViewRestrictions: List<DataViewRestrictions>
abstract val objectRelationLinks: List<RelationLink>
abstract val dataViewContent: DV
abstract val dataViewBlock: Block
abstract val viewers: List<DVViewer>
@ -27,7 +31,8 @@ sealed class ObjectState {
override val blocks: List<Block> = emptyList(),
override val details: Map<Id, Block.Fields> = emptyMap(),
override val objectRestrictions: List<ObjectRestriction> = emptyList(),
override val dataViewRestrictions: List<DataViewRestrictions> = emptyList()
override val dataViewRestrictions: List<DataViewRestrictions> = emptyList(),
override val objectRelationLinks: List<RelationLink> = emptyList()
) : DataView() {
override val isInitialized get() = blocks.any { it.content is DV }
@ -41,7 +46,8 @@ sealed class ObjectState {
override val blocks: List<Block> = emptyList(),
override val details: Map<Id, Block.Fields> = emptyMap(),
override val objectRestrictions: List<ObjectRestriction> = emptyList(),
override val dataViewRestrictions: List<DataViewRestrictions> = emptyList()
override val dataViewRestrictions: List<DataViewRestrictions> = emptyList(),
override val objectRelationLinks: List<RelationLink> = emptyList()
) : DataView() {
override val isInitialized get() = blocks.any { it.content is DV }