Objects | Feature | Delete relations from object (#1741)
* added delete actions * fixed tests * added request for deleting relation from object * fixes * fixes * added restrictions * run ci * ci off, fixes
This commit is contained in:
parent
9b42bc3719
commit
1f4fe5829d
|
@ -7,6 +7,7 @@ import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
|||
import com.anytypeio.anytype.domain.dataview.interactor.ObjectRelationList
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.relations.AddToFeaturedRelations
|
||||
import com.anytypeio.anytype.domain.relations.DeleteRelationFromObject
|
||||
import com.anytypeio.anytype.domain.relations.RemoveFromFeaturedRelations
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
import com.anytypeio.anytype.presentation.editor.editor.DetailModificationManager
|
||||
|
@ -43,7 +44,8 @@ object DocumentRelationModule {
|
|||
updateDetail: UpdateDetail,
|
||||
detailModificationManager: DetailModificationManager,
|
||||
addToFeaturedRelations: AddToFeaturedRelations,
|
||||
removeFromFeaturedRelations: RemoveFromFeaturedRelations
|
||||
removeFromFeaturedRelations: RemoveFromFeaturedRelations,
|
||||
deleteRelationFromObject: DeleteRelationFromObject
|
||||
): ObjectRelationListViewModelFactory {
|
||||
return ObjectRelationListViewModelFactory(
|
||||
stores = stores,
|
||||
|
@ -53,7 +55,8 @@ object DocumentRelationModule {
|
|||
updateDetail = updateDetail,
|
||||
detailModificationManager = detailModificationManager,
|
||||
addToFeaturedRelations = addToFeaturedRelations,
|
||||
removeFromFeaturedRelations = removeFromFeaturedRelations
|
||||
removeFromFeaturedRelations = removeFromFeaturedRelations,
|
||||
deleteRelationFromObject = deleteRelationFromObject
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -73,4 +76,9 @@ object DocumentRelationModule {
|
|||
@Provides
|
||||
@PerModal
|
||||
fun removeFromFeaturedRelations(repo: BlockRepository) : RemoveFromFeaturedRelations = RemoveFromFeaturedRelations(repo)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerModal
|
||||
fun deleteRelationFromObject(repo: BlockRepository) : DeleteRelationFromObject = DeleteRelationFromObject(repo)
|
||||
}
|
|
@ -58,6 +58,12 @@ open class RelationListFragment : BaseBottomSheetFragment(),
|
|||
ctx = ctx,
|
||||
view = it.view
|
||||
)
|
||||
},
|
||||
onDeleteClicked = {
|
||||
vm.onDeleteClicked(
|
||||
ctx = ctx,
|
||||
view = it.view
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -92,7 +98,7 @@ open class RelationListFragment : BaseBottomSheetFragment(),
|
|||
RelationAddToObjectFragment.new(ctx).show(childFragmentManager, null)
|
||||
}
|
||||
btnEditOrDone.setOnClickListener {
|
||||
toast(getString(R.string.coming_soon))
|
||||
vm.onEditOrDoneClicked()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,6 +132,15 @@ open class RelationListFragment : BaseBottomSheetFragment(),
|
|||
}
|
||||
subscribe(vm.commands) { command -> execute(command) }
|
||||
subscribe(vm.toasts) { toast(it) }
|
||||
subscribe(vm.isEditMode) { isEditMode ->
|
||||
if (isEditMode) {
|
||||
btnEditOrDone.setText(R.string.done)
|
||||
btnPlus.invisible()
|
||||
} else {
|
||||
btnPlus.visible()
|
||||
btnEditOrDone.setText(R.string.edit)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,16 +4,40 @@ package com.anytypeio.anytype.core_models
|
|||
* Keys for predefined, bundled relations.
|
||||
*/
|
||||
object Relations {
|
||||
const val ID = "id"
|
||||
const val COVER_TYPE = "coverType"
|
||||
const val DESCRIPTION = "description"
|
||||
const val LAYOUT = "layout"
|
||||
const val NAME = "name"
|
||||
const val ICON_EMOJI = "iconEmoji"
|
||||
const val ICON_IMAGE = "iconImage"
|
||||
const val RELATION_FORMAT = "relationFormat"
|
||||
const val IS_ARCHIVED = "isArchived"
|
||||
const val IS_READ_ONLY = "isReadonly"
|
||||
const val IS_HIDDEN = "isHidden"
|
||||
const val LAST_OPENED_DATE = "lastOpenedDate"
|
||||
const val TYPE = "type"
|
||||
const val DONE = "done"
|
||||
const val FEATURED_RELATIONS = "featuredRelations"
|
||||
const val FILE_EXT = "fileExt"
|
||||
const val FILE_MIME_TYPE = "fileMimeType"
|
||||
|
||||
const val NUMBER_DEFAULT_VALUE = "0"
|
||||
|
||||
val defaultRelations = listOf(
|
||||
ID,
|
||||
NAME,
|
||||
DESCRIPTION,
|
||||
ICON_EMOJI,
|
||||
ICON_IMAGE,
|
||||
RELATION_FORMAT,
|
||||
TYPE,
|
||||
LAYOUT,
|
||||
IS_HIDDEN,
|
||||
IS_ARCHIVED,
|
||||
IS_READ_ONLY,
|
||||
DONE,
|
||||
FILE_EXT,
|
||||
FILE_MIME_TYPE
|
||||
)
|
||||
}
|
|
@ -32,6 +32,12 @@ sealed class RelationViewHolder(view: View) : BlockViewHolder(view), BlockViewHo
|
|||
}
|
||||
}
|
||||
|
||||
fun setIsRemovable(isRemoveable: Boolean) {
|
||||
itemView.findViewById<View>(R.id.actionsLeftContainer).apply {
|
||||
if (isRemoveable) visible() else gone()
|
||||
}
|
||||
}
|
||||
|
||||
fun setBackgroundColor(color: String? = null) {
|
||||
Timber.d("Setting background color: $color")
|
||||
if (color != null) {
|
||||
|
|
|
@ -8,7 +8,6 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.features.editor.holders.relations.RelationViewHolder
|
||||
import com.anytypeio.anytype.core_ui.features.editor.slash.holders.RelationsSubheaderMenuHolder
|
||||
import com.anytypeio.anytype.core_ui.features.relations.DocumentRelationAdapter
|
||||
import com.anytypeio.anytype.core_utils.diff.DefaultDiffUtil
|
||||
import com.anytypeio.anytype.core_utils.ext.gone
|
||||
import com.anytypeio.anytype.core_utils.ext.visible
|
||||
|
@ -117,15 +116,6 @@ class SlashRelationsAdapter(
|
|||
}
|
||||
}
|
||||
}
|
||||
R.layout.item_relation_list_section -> {
|
||||
DocumentRelationAdapter.SectionViewHolder(
|
||||
view = inflater.inflate(
|
||||
viewType,
|
||||
parent,
|
||||
false
|
||||
)
|
||||
)
|
||||
}
|
||||
R.layout.item_slash_widget_subheader -> {
|
||||
RelationsSubheaderMenuHolder(
|
||||
view = inflater.inflate(viewType, parent, false)
|
||||
|
|
|
@ -16,7 +16,8 @@ import com.anytypeio.anytype.core_ui.features.editor.holders.relations.RelationV
|
|||
class DocumentRelationAdapter(
|
||||
private var items: List<RelationListViewModel.Model>,
|
||||
private val onRelationClicked: (RelationListViewModel.Model.Item) -> Unit,
|
||||
private val onCheckboxClicked: (RelationListViewModel.Model.Item) -> Unit
|
||||
private val onCheckboxClicked: (RelationListViewModel.Model.Item) -> Unit,
|
||||
private val onDeleteClicked: (RelationListViewModel.Model.Item) -> Unit
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
|
@ -34,6 +35,14 @@ class DocumentRelationAdapter(
|
|||
check(view is RelationListViewModel.Model.Item)
|
||||
onCheckboxClicked(view)
|
||||
}
|
||||
itemView.findViewById<View>(R.id.ivActionDelete).setOnClickListener {
|
||||
val pos = bindingAdapterPosition
|
||||
if (pos != RecyclerView.NO_POSITION) {
|
||||
val view = items[bindingAdapterPosition]
|
||||
check(view is RelationListViewModel.Model.Item)
|
||||
onDeleteClicked(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
R.layout.item_relation_list_relation_checkbox -> {
|
||||
|
@ -48,6 +57,14 @@ class DocumentRelationAdapter(
|
|||
check(view is RelationListViewModel.Model.Item)
|
||||
onCheckboxClicked(view)
|
||||
}
|
||||
itemView.findViewById<View>(R.id.ivActionDelete).setOnClickListener {
|
||||
val pos = bindingAdapterPosition
|
||||
if (pos != RecyclerView.NO_POSITION) {
|
||||
val view = items[bindingAdapterPosition]
|
||||
check(view is RelationListViewModel.Model.Item)
|
||||
onDeleteClicked(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
R.layout.item_relation_list_relation_object -> {
|
||||
|
@ -62,6 +79,14 @@ class DocumentRelationAdapter(
|
|||
check(view is RelationListViewModel.Model.Item)
|
||||
onCheckboxClicked(view)
|
||||
}
|
||||
itemView.findViewById<View>(R.id.ivActionDelete).setOnClickListener {
|
||||
val pos = bindingAdapterPosition
|
||||
if (pos != RecyclerView.NO_POSITION) {
|
||||
val view = items[bindingAdapterPosition]
|
||||
check(view is RelationListViewModel.Model.Item)
|
||||
onDeleteClicked(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
R.layout.item_relation_list_relation_status -> {
|
||||
|
@ -76,6 +101,14 @@ class DocumentRelationAdapter(
|
|||
check(view is RelationListViewModel.Model.Item)
|
||||
onCheckboxClicked(view)
|
||||
}
|
||||
itemView.findViewById<View>(R.id.ivActionDelete).setOnClickListener {
|
||||
val pos = bindingAdapterPosition
|
||||
if (pos != RecyclerView.NO_POSITION) {
|
||||
val view = items[bindingAdapterPosition]
|
||||
check(view is RelationListViewModel.Model.Item)
|
||||
onDeleteClicked(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
R.layout.item_relation_list_relation_tag -> {
|
||||
|
@ -90,6 +123,14 @@ class DocumentRelationAdapter(
|
|||
check(view is RelationListViewModel.Model.Item)
|
||||
onCheckboxClicked(view)
|
||||
}
|
||||
itemView.findViewById<View>(R.id.ivActionDelete).setOnClickListener {
|
||||
val pos = bindingAdapterPosition
|
||||
if (pos != RecyclerView.NO_POSITION) {
|
||||
val view = items[bindingAdapterPosition]
|
||||
check(view is RelationListViewModel.Model.Item)
|
||||
onDeleteClicked(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
R.layout.item_relation_list_relation_file -> {
|
||||
|
@ -104,6 +145,14 @@ class DocumentRelationAdapter(
|
|||
check(view is RelationListViewModel.Model.Item)
|
||||
onCheckboxClicked(view)
|
||||
}
|
||||
itemView.findViewById<View>(R.id.ivActionDelete).setOnClickListener {
|
||||
val pos = bindingAdapterPosition
|
||||
if (pos != RecyclerView.NO_POSITION) {
|
||||
val view = items[bindingAdapterPosition]
|
||||
check(view is RelationListViewModel.Model.Item)
|
||||
onDeleteClicked(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
R.layout.item_relation_list_section -> {
|
||||
|
@ -113,6 +162,32 @@ class DocumentRelationAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(
|
||||
holder: RecyclerView.ViewHolder,
|
||||
position: Int,
|
||||
payloads: MutableList<Any>
|
||||
) {
|
||||
if (payloads.isEmpty()) {
|
||||
super.onBindViewHolder(holder, position, payloads)
|
||||
} else {
|
||||
if (holder is ViewHolder) {
|
||||
payloads.forEach { payload ->
|
||||
if (payload is GranularChange) {
|
||||
if (payload.isModeChanged) {
|
||||
val item = items[position]
|
||||
check(item is RelationListViewModel.Model.Item)
|
||||
holder.setIsRemovable(item.isRemoveable)
|
||||
} else {
|
||||
super.onBindViewHolder(holder, position, payloads)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
super.onBindViewHolder(holder, position, payloads)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
val item = items[position]
|
||||
when (holder) {
|
||||
|
@ -156,11 +231,14 @@ class DocumentRelationAdapter(
|
|||
check(item is RelationListViewModel.Model.Section)
|
||||
holder.bind(item)
|
||||
}
|
||||
else -> { Timber.d("Skipping binding for: $holder") }
|
||||
else -> {
|
||||
Timber.d("Skipping binding for: $holder")
|
||||
}
|
||||
}
|
||||
if (holder is ViewHolder) {
|
||||
check(item is RelationListViewModel.Model.Item)
|
||||
holder.setIsFeatured(item.view.isFeatured)
|
||||
holder.setIsRemovable(item.isRemoveable)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,7 +246,7 @@ class DocumentRelationAdapter(
|
|||
|
||||
override fun getItemViewType(position: Int): Int = when (val item = items[position]) {
|
||||
is RelationListViewModel.Model.Item -> {
|
||||
when(item.view) {
|
||||
when (item.view) {
|
||||
is DocumentRelationView.Checkbox -> R.layout.item_relation_list_relation_checkbox
|
||||
is DocumentRelationView.Object -> R.layout.item_relation_list_relation_object
|
||||
is DocumentRelationView.Status -> R.layout.item_relation_list_relation_status
|
||||
|
@ -184,7 +262,7 @@ class DocumentRelationAdapter(
|
|||
|
||||
fun update(update: List<RelationListViewModel.Model>) {
|
||||
Timber.d("Updating adapter: $update")
|
||||
val differ = DefaultDiffUtil(old = items, new = update)
|
||||
val differ = Differ(old = items, new = update)
|
||||
val result = DiffUtil.calculateDiff(differ, false)
|
||||
items = update
|
||||
result.dispatchUpdatesTo(this)
|
||||
|
@ -192,7 +270,7 @@ class DocumentRelationAdapter(
|
|||
|
||||
class SectionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
fun bind(section: RelationListViewModel.Model.Section) {
|
||||
when(section) {
|
||||
when (section) {
|
||||
RelationListViewModel.Model.Section.Featured -> {
|
||||
itemView.tvSectionName.setText(R.string.featured_relations)
|
||||
}
|
||||
|
@ -203,4 +281,23 @@ class DocumentRelationAdapter(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Differ(
|
||||
private val old: List<RelationListViewModel.Model>,
|
||||
private val new: List<RelationListViewModel.Model>
|
||||
) : DefaultDiffUtil<RelationListViewModel.Model>(old = old, new = new) {
|
||||
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
|
||||
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)
|
||||
GranularChange(isModeChanged = true)
|
||||
else
|
||||
null
|
||||
} else
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
data class GranularChange(val isModeChanged: Boolean = false)
|
||||
}
|
|
@ -9,6 +9,20 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/actionsLeftContainer"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:visibility="gone">
|
||||
<ImageView
|
||||
android:id="@+id/ivActionDelete"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/ic_relation_delete" />
|
||||
</FrameLayout>
|
||||
|
||||
<include
|
||||
layout="@layout/item_document_relation_checkbox"
|
||||
android:layout_width="0dp"
|
||||
|
|
|
@ -1,14 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:background="@drawable/default_ripple"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/default_ripple">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/actionsLeftContainer"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:visibility="gone">
|
||||
<ImageView
|
||||
android:id="@+id/ivActionDelete"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/ic_relation_delete" />
|
||||
</FrameLayout>
|
||||
|
||||
<include
|
||||
layout="@layout/item_document_relation_default"
|
||||
android:layout_width="0dp"
|
||||
|
@ -27,9 +41,9 @@
|
|||
|
||||
<include
|
||||
android:id="@+id/divider"
|
||||
layout="@layout/view_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
layout="@layout/view_divider"
|
||||
android:layout_gravity="bottom"
|
||||
android:visibility="gone" />
|
||||
|
||||
|
|
|
@ -1,14 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:background="@drawable/default_ripple"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/default_ripple">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/actionsLeftContainer"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:visibility="gone">
|
||||
<ImageView
|
||||
android:id="@+id/ivActionDelete"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/ic_relation_delete" />
|
||||
</FrameLayout>
|
||||
|
||||
<include
|
||||
layout="@layout/item_document_relation_file"
|
||||
android:layout_width="0dp"
|
||||
|
@ -27,9 +41,9 @@
|
|||
|
||||
<include
|
||||
android:id="@+id/divider"
|
||||
layout="@layout/view_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
layout="@layout/view_divider"
|
||||
android:layout_gravity="bottom"
|
||||
android:visibility="gone" />
|
||||
|
||||
|
|
|
@ -9,6 +9,20 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/actionsLeftContainer"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:visibility="gone">
|
||||
<ImageView
|
||||
android:id="@+id/ivActionDelete"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/ic_relation_delete" />
|
||||
</FrameLayout>
|
||||
|
||||
<include
|
||||
layout="@layout/item_document_relation_object"
|
||||
android:layout_width="0dp"
|
||||
|
|
|
@ -9,6 +9,20 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/actionsLeftContainer"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:visibility="gone">
|
||||
<ImageView
|
||||
android:id="@+id/ivActionDelete"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/ic_relation_delete" />
|
||||
</FrameLayout>
|
||||
|
||||
<include
|
||||
layout="@layout/item_document_relation_status"
|
||||
android:layout_width="0dp"
|
||||
|
|
|
@ -9,6 +9,20 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/actionsLeftContainer"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:visibility="gone">
|
||||
<ImageView
|
||||
android:id="@+id/ivActionDelete"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/ic_relation_delete" />
|
||||
</FrameLayout>
|
||||
|
||||
<include
|
||||
layout="@layout/item_document_relation_tag"
|
||||
android:layout_width="0dp"
|
||||
|
|
|
@ -7,7 +7,7 @@ import androidx.recyclerview.widget.DiffUtil
|
|||
* [T] should also implement [DefaultObjectDiffIdentifier]. Otherwise, [areItemsTheSame] won't work.
|
||||
* @see [DefaultObjectDiffIdentifier]
|
||||
*/
|
||||
class DefaultDiffUtil<in T : DefaultObjectDiffIdentifier>(
|
||||
open class DefaultDiffUtil<in T : DefaultObjectDiffIdentifier>(
|
||||
private val old: List<T>,
|
||||
private val new: List<T>
|
||||
) : DiffUtil.Callback() {
|
||||
|
|
|
@ -427,6 +427,10 @@ class BlockDataRepository(
|
|||
ctx: Id, relation: Id
|
||||
): Payload = factory.remote.addRelationToObject(ctx, relation)
|
||||
|
||||
override suspend fun deleteRelationFromObject(ctx: Id, relation: Id): Payload {
|
||||
return factory.remote.deleteRelationFromObject(ctx = ctx, relation = relation)
|
||||
}
|
||||
|
||||
override suspend fun addNewRelationToObject(
|
||||
ctx: Id,
|
||||
name: String,
|
||||
|
|
|
@ -154,6 +154,7 @@ interface BlockDataStore {
|
|||
|
||||
suspend fun relationListAvailable(ctx: Id): List<Relation>
|
||||
suspend fun addRelationToObject(ctx: Id, relation: Id) : Payload
|
||||
suspend fun deleteRelationFromObject(ctx: Id, relation: Id): Payload
|
||||
suspend fun addNewRelationToObject(ctx: Id, name: String, format: RelationFormat) : Payload
|
||||
|
||||
suspend fun debugSync(): String
|
||||
|
|
|
@ -160,6 +160,7 @@ interface BlockRemote {
|
|||
|
||||
suspend fun relationListAvailable(ctx: Id): List<Relation>
|
||||
suspend fun addRelationToObject(ctx: Id, relation: Id) : Payload
|
||||
suspend fun deleteRelationFromObject(ctx: Id, relation: Id): Payload
|
||||
suspend fun addNewRelationToObject(ctx: Id, name: String, format: RelationFormat) : Payload
|
||||
|
||||
suspend fun debugSync(): String
|
||||
|
|
|
@ -348,7 +348,7 @@ class BlockRemoteDataStore(private val remote: BlockRemote) : BlockDataStore {
|
|||
override suspend fun addRelationToObject(
|
||||
ctx: Id,
|
||||
relation: Id
|
||||
): Payload = remote.addRelationToObject(ctx, relation)
|
||||
): Payload = remote.addRelationToObject(ctx = ctx, relation = relation)
|
||||
|
||||
override suspend fun addNewRelationToObject(
|
||||
ctx: Id,
|
||||
|
@ -360,6 +360,11 @@ class BlockRemoteDataStore(private val remote: BlockRemote) : BlockDataStore {
|
|||
name = name
|
||||
)
|
||||
|
||||
override suspend fun deleteRelationFromObject(
|
||||
ctx: Id,
|
||||
relation: Id
|
||||
): Payload = remote.deleteRelationFromObject(ctx = ctx, relation = relation)
|
||||
|
||||
override suspend fun debugSync(): String = remote.debugSync()
|
||||
|
||||
override suspend fun turnInto(
|
||||
|
|
|
@ -209,6 +209,7 @@ interface BlockRepository {
|
|||
suspend fun relationListAvailable(ctx: Id): List<Relation>
|
||||
|
||||
suspend fun addRelationToObject(ctx: Id, relation: Id): Payload
|
||||
suspend fun deleteRelationFromObject(ctx: Id, relation: Id): Payload
|
||||
suspend fun addNewRelationToObject(ctx: Id, name: String, format: RelationFormat): Payload
|
||||
|
||||
suspend fun debugSync(): String
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package com.anytypeio.anytype.domain.relations
|
||||
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.domain.base.BaseUseCase
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
|
||||
/**
|
||||
* Use-case for deleting a relation from an object.
|
||||
*/
|
||||
class DeleteRelationFromObject(
|
||||
private val repo: BlockRepository
|
||||
) : BaseUseCase<Payload, DeleteRelationFromObject.Params>() {
|
||||
|
||||
override suspend fun run(params: Params) = safe {
|
||||
repo.deleteRelationFromObject(
|
||||
ctx = params.ctx,
|
||||
relation = params.relation
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ctx id of the object
|
||||
* @param relation relation id or key
|
||||
*/
|
||||
class Params(
|
||||
val ctx: Id,
|
||||
val relation: Id
|
||||
)
|
||||
}
|
|
@ -379,6 +379,14 @@ class BlockMiddleware(
|
|||
name = name
|
||||
)
|
||||
|
||||
override suspend fun deleteRelationFromObject(
|
||||
ctx: Id,
|
||||
relation: Id
|
||||
): Payload = middleware.deleteRelationFromObject(
|
||||
ctx = ctx,
|
||||
relation = relation
|
||||
)
|
||||
|
||||
override suspend fun debugSync(): String = middleware.debugSync()
|
||||
|
||||
override suspend fun turnInto(
|
||||
|
|
|
@ -1416,6 +1416,17 @@ class Middleware(
|
|||
return response.event.toPayload()
|
||||
}
|
||||
|
||||
fun deleteRelationFromObject(ctx: Id, relation: Id) : Payload {
|
||||
val request = Rpc.Object.RelationDelete.Request(
|
||||
contextId = ctx,
|
||||
relationKey = relation
|
||||
)
|
||||
if (BuildConfig.DEBUG) logRequest(request)
|
||||
val response = service.objectRelationDelete(request)
|
||||
if (BuildConfig.DEBUG) logResponse(response)
|
||||
return response.event.toPayload()
|
||||
}
|
||||
|
||||
fun addToFeaturedRelations(
|
||||
ctx: Id,
|
||||
relations: List<Id>
|
||||
|
|
|
@ -168,6 +168,9 @@ interface MiddlewareService {
|
|||
@Throws(Exception::class)
|
||||
fun objectRelationAdd(request: Object.RelationAdd.Request) : Object.RelationAdd.Response
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun objectRelationDelete(request: Object.RelationDelete.Request) : Object.RelationDelete.Response
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun debugSync(request: Debug.Sync.Request) : Debug.Sync.Response
|
||||
|
||||
|
|
|
@ -656,6 +656,19 @@ class MiddlewareServiceImplementation : MiddlewareService {
|
|||
}
|
||||
}
|
||||
|
||||
override fun objectRelationDelete(request: Object.RelationDelete.Request): Object.RelationDelete.Response {
|
||||
val encoded = Service.objectRelationDelete(
|
||||
Object.RelationDelete.Request.ADAPTER.encode(request)
|
||||
)
|
||||
val response = Object.RelationDelete.Response.ADAPTER.decode(encoded)
|
||||
val error = response.error
|
||||
if (error != null && error.code != Object.RelationDelete.Response.Error.Code.NULL) {
|
||||
throw Exception(error.description)
|
||||
} else {
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
||||
override fun blockAddRelation(request: Block.Relation.Add.Request): Block.Relation.Add.Response {
|
||||
val encoded = Service.blockRelationAdd(
|
||||
Block.Relation.Add.Request.ADAPTER.encode(request)
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.anytypeio.anytype.domain.`object`.UpdateDetail
|
|||
import com.anytypeio.anytype.domain.dataview.interactor.ObjectRelationList
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.relations.AddToFeaturedRelations
|
||||
import com.anytypeio.anytype.domain.relations.DeleteRelationFromObject
|
||||
import com.anytypeio.anytype.domain.relations.RemoveFromFeaturedRelations
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
import com.anytypeio.anytype.presentation.editor.editor.DetailModificationManager
|
||||
|
@ -20,7 +21,8 @@ class ObjectRelationListViewModelFactory(
|
|||
private val updateDetail: UpdateDetail,
|
||||
private val detailModificationManager: DetailModificationManager,
|
||||
private val addToFeaturedRelations: AddToFeaturedRelations,
|
||||
private val removeFromFeaturedRelations: RemoveFromFeaturedRelations
|
||||
private val removeFromFeaturedRelations: RemoveFromFeaturedRelations,
|
||||
private val deleteRelationFromObject: DeleteRelationFromObject
|
||||
) : ViewModelProvider.Factory {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
@ -33,7 +35,8 @@ class ObjectRelationListViewModelFactory(
|
|||
updateDetail = updateDetail,
|
||||
detailModificationManager = detailModificationManager,
|
||||
addToFeaturedRelations = addToFeaturedRelations,
|
||||
removeFromFeaturedRelations = removeFromFeaturedRelations
|
||||
removeFromFeaturedRelations = removeFromFeaturedRelations,
|
||||
deleteRelationFromObject = deleteRelationFromObject
|
||||
) as T
|
||||
}
|
||||
}
|
|
@ -4,11 +4,13 @@ import androidx.lifecycle.viewModelScope
|
|||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.core_models.Relation
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_utils.diff.DefaultObjectDiffIdentifier
|
||||
import com.anytypeio.anytype.domain.`object`.UpdateDetail
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.ObjectRelationList
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.relations.AddToFeaturedRelations
|
||||
import com.anytypeio.anytype.domain.relations.DeleteRelationFromObject
|
||||
import com.anytypeio.anytype.domain.relations.RemoveFromFeaturedRelations
|
||||
import com.anytypeio.anytype.presentation.common.BaseViewModel
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
|
@ -27,9 +29,12 @@ class RelationListViewModel(
|
|||
private val updateDetail: UpdateDetail,
|
||||
private val detailModificationManager: DetailModificationManager,
|
||||
private val addToFeaturedRelations: AddToFeaturedRelations,
|
||||
private val removeFromFeaturedRelations: RemoveFromFeaturedRelations
|
||||
private val removeFromFeaturedRelations: RemoveFromFeaturedRelations,
|
||||
private val deleteRelationFromObject: DeleteRelationFromObject
|
||||
) : BaseViewModel() {
|
||||
|
||||
val isEditMode = MutableStateFlow(false)
|
||||
|
||||
private val jobs = mutableListOf<Job>()
|
||||
|
||||
private val isInAddMode = MutableStateFlow(false)
|
||||
|
@ -43,7 +48,12 @@ class RelationListViewModel(
|
|||
val detail = details.details[ctx]
|
||||
val values = detail?.map ?: emptyMap()
|
||||
val featured = detail?.featuredRelations ?: emptyList()
|
||||
relations.views(details, values, urlBuilder, featured).map { Model.Item(it) }
|
||||
relations.views(details, values, urlBuilder, featured).map { view ->
|
||||
Model.Item(
|
||||
view = view,
|
||||
isRemoveable = isEditMode.value && !Relations.defaultRelations.contains(view.relationId)
|
||||
)
|
||||
}
|
||||
}.map { views ->
|
||||
val result = mutableListOf<Model>().apply {
|
||||
val (isFeatured, other) = views.partition { it.view.isFeatured }
|
||||
|
@ -111,6 +121,33 @@ class RelationListViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
fun onDeleteClicked(ctx: Id, view: DocumentRelationView) {
|
||||
viewModelScope.launch {
|
||||
deleteRelationFromObject(
|
||||
DeleteRelationFromObject.Params(
|
||||
ctx = ctx,
|
||||
relation = view.relationId
|
||||
)
|
||||
).process(
|
||||
failure = { Timber.e(it, "Error while deleting relation") },
|
||||
success = { dispatcher.send(it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun onEditOrDoneClicked() {
|
||||
isEditMode.value = !isEditMode.value
|
||||
views.value = views.value.map { view ->
|
||||
if (view is Model.Item) {
|
||||
view.copy(
|
||||
isRemoveable = isEditMode.value && !Relations.defaultRelations.contains(view.view.relationId)
|
||||
)
|
||||
} else {
|
||||
view
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onRelationClickedAddMode(
|
||||
target: Id?,
|
||||
view: DocumentRelationView
|
||||
|
@ -237,12 +274,16 @@ class RelationListViewModel(
|
|||
object Featured : Section() {
|
||||
override val identifier: String get() = "Section_Featured"
|
||||
}
|
||||
|
||||
object Other : Section() {
|
||||
override val identifier: String get() = "Section_Other"
|
||||
}
|
||||
}
|
||||
|
||||
data class Item(val view: DocumentRelationView) : Model() {
|
||||
data class Item(
|
||||
val view: DocumentRelationView,
|
||||
val isRemoveable: Boolean = false
|
||||
) : Model() {
|
||||
override val identifier: String get() = view.identifier
|
||||
}
|
||||
}
|
||||
|
@ -273,8 +314,6 @@ class RelationListViewModel(
|
|||
}
|
||||
|
||||
companion object {
|
||||
const val MAX_FEATURED_RELATION_COUNT = 5
|
||||
const val MAX_FEATURED_RELATION_COUNT_ERROR = "Currently you cannot create more than $MAX_FEATURED_RELATION_COUNT featured relations"
|
||||
const val NOT_ALLOWED_FOR_RELATION = "Not allowed for this relation"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user