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

DROID-944 Library | Enhancement | Implemented installing and uninstalling types and relations (#2898)

DROID-944 Library | Enhancement | Implemented installing and uninstalling types and relations
This commit is contained in:
Allan Quatermain 2023-02-09 14:24:20 +04:00 committed by GitHub
parent 9c70819e1a
commit b3f6835056
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 398 additions and 81 deletions

View file

@ -9,4 +9,9 @@ sealed class LibraryEvent {
class LibraryRelations(override val query: String) : Query(query)
}
sealed class ToggleInstall(open val item: LibraryView) : LibraryEvent() {
class Type(override val item: LibraryView) : ToggleInstall(item)
class Relation(override val item: LibraryView) : ToggleInstall(item)
}
}

View file

@ -1,7 +1,6 @@
package com.anytypeio.anytype.presentation.library
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.presentation.navigation.LibraryView
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow

View file

@ -0,0 +1,41 @@
package com.anytypeio.anytype.presentation.library
import android.content.Context
import android.content.res.Resources
import com.anytypeio.anytype.presentation.R
import javax.inject.Inject
interface LibraryResourceManager {
fun messageRelationAdded(name: String): String
fun messageRelationRemoved(name: String): String
fun messageTypeAdded(name: String): String
fun messageTypeRemoved(name: String): String
val errorMessage: String
class Impl @Inject constructor(
val context: Context
) : LibraryResourceManager {
private val resources: Resources = context.resources
override fun messageRelationAdded(name: String) =
resources.getString(R.string.library_relation_added, name)
override fun messageRelationRemoved(name: String) =
resources.getString(R.string.library_relation_removed, name)
override fun messageTypeAdded(name: String) =
resources.getString(R.string.library_type_added, name)
override fun messageTypeRemoved(name: String) =
resources.getString(R.string.library_type_removed, name)
override val errorMessage: String =
resources.getString(R.string.library_something_went_wrong)
}
}

View file

@ -1,6 +1,5 @@
package com.anytypeio.anytype.presentation.library
import com.anytypeio.anytype.presentation.navigation.LibraryView
class LibraryScreenState(
val types: Tabs.Types,

View file

@ -0,0 +1,67 @@
package com.anytypeio.anytype.presentation.library
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.RelationFormat
import com.anytypeio.anytype.presentation.objects.ObjectIcon
sealed interface DependentData {
class Model(
val item: LibraryView,
) : DependentData
object None : DependentData
}
sealed interface LibraryView {
val id: Id
val name: String
val dependentData: DependentData
class MyTypeView(
override val id: Id,
override val name: String,
val icon: ObjectIcon? = null,
val sourceObject: Id? = null,
val readOnly: Boolean = false,
override val dependentData: DependentData = DependentData.None
) : LibraryView
data class LibraryTypeView(
override val id: Id,
override val name: String,
val icon: ObjectIcon? = null,
val objectTypeId: Id? = null,
override val dependentData: DependentData = DependentData.None
) : LibraryView
class MyRelationView(
override val id: Id,
override val name: String,
val format: RelationFormat,
val sourceObject: Id? = null,
val readOnly: Boolean = false,
override val dependentData: DependentData = DependentData.None
) : LibraryView
data class LibraryRelationView(
override val id: Id,
override val name: String,
val format: RelationFormat,
override val dependentData: DependentData = DependentData.None
) : LibraryView
class UnknownView(
override val id: Id = "",
override val name: String = "",
override val dependentData: DependentData = DependentData.None
) : LibraryView
class CreateNewTypeView(
override val id: Id = "",
override val name: String = "",
override val dependentData: DependentData = DependentData.None
) : LibraryView
}

View file

@ -3,11 +3,15 @@ package com.anytypeio.anytype.presentation.library
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.domain.base.fold
import com.anytypeio.anytype.domain.workspace.AddObjectToWorkspace
import com.anytypeio.anytype.domain.workspace.RemoveObjectsFromWorkspace
import com.anytypeio.anytype.presentation.common.BaseViewModel
import com.anytypeio.anytype.presentation.library.delegates.LibraryRelationsDelegate
import com.anytypeio.anytype.presentation.library.delegates.LibraryTypesDelegate
import com.anytypeio.anytype.presentation.library.delegates.MyRelationsDelegate
import com.anytypeio.anytype.presentation.library.delegates.MyTypesDelegate
import com.anytypeio.anytype.presentation.navigation.LibraryView
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@ -15,13 +19,17 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import timber.log.Timber
class LibraryViewModel(
private val myTypesDelegate: MyTypesDelegate,
private val libraryTypesDelegate: LibraryTypesDelegate,
private val myRelationsDelegate: MyRelationsDelegate,
private val libraryRelationsDelegate: LibraryRelationsDelegate
) : ViewModel() {
private val libraryRelationsDelegate: LibraryRelationsDelegate,
private val addObjectToWorkspace: AddObjectToWorkspace,
private val removeObjectsFromWorkspace: RemoveObjectsFromWorkspace,
private val resourceManager: LibraryResourceManager
) : BaseViewModel() {
private val uiEvents = MutableStateFlow<LibraryEvent>(LibraryEvent.Query.MyTypes(""))
@ -41,11 +49,75 @@ class LibraryViewModel(
is LibraryEvent.Query.LibraryRelations -> {
libraryRelationsDelegate.onQueryLibRelations(it.query)
}
is LibraryEvent.ToggleInstall -> {
proceedWithToggleInstall(it.item)
}
}
}
}
}
private fun proceedWithToggleInstall(item: LibraryView) {
when (val dependentData = item.dependentData) {
is DependentData.Model -> {
proceedWithUnInstallingObject(item, dependentData.item.id)
}
is DependentData.None -> {
proceedWithInstallingObject(item)
}
}
}
private fun proceedWithInstallingObject(item: LibraryView) {
viewModelScope.launch {
addObjectToWorkspace(AddObjectToWorkspace.Params(listOf(item.id))).proceed(
success = {
when (item) {
is LibraryView.LibraryRelationView -> {
sendToast(resourceManager.messageRelationAdded(item.name))
}
is LibraryView.LibraryTypeView -> {
sendToast(resourceManager.messageTypeAdded(item.name))
}
else -> {
Timber.e("Unsupported item type: $item")
}
}
},
failure = {
Timber.e(it, "Error while adding relation to workspace.")
sendToast(resourceManager.errorMessage)
}
)
}
}
private fun proceedWithUnInstallingObject(item: LibraryView, id: Id) {
viewModelScope.launch {
removeObjectsFromWorkspace.execute(
RemoveObjectsFromWorkspace.Params(listOf(id))
).fold(
onFailure = {
Timber.e(it, "Error while removing relation from workspace.")
sendToast(resourceManager.errorMessage)
},
onSuccess = {
when (item) {
is LibraryView.LibraryRelationView -> {
sendToast(resourceManager.messageRelationRemoved(item.name))
}
is LibraryView.LibraryTypeView -> {
sendToast(resourceManager.messageTypeRemoved(item.name))
}
else -> {
Timber.e("Unsupported item type: $item")
}
}
}
)
}
}
fun eventStream(event: LibraryEvent) {
uiEvents.value = event
}
@ -93,9 +165,17 @@ class LibraryViewModel(
return libTypes.copy(
items = libTypes.items.map { libType ->
if (libType is LibraryView.LibraryTypeView) {
libType.copy(installed = myTypes.items.find { myType ->
(myType as? LibraryView.MyTypeView)?.sourceObject == libType.id
} != null)
with(
myTypes.items.find {
(it as? LibraryView.MyTypeView)?.sourceObject == libType.id
}
) {
libType.copy(
dependentData = if (this != null) {
DependentData.Model(item = this)
} else DependentData.None
)
}
} else {
libType
}
@ -110,9 +190,17 @@ class LibraryViewModel(
return libRelations.copy(
items = libRelations.items.map { libRelation ->
if (libRelation is LibraryView.LibraryRelationView) {
libRelation.copy(installed = myRelations.items.find { myType ->
(myType as LibraryView.MyRelationView).sourceObject == libRelation.id
} != null)
with(
myRelations.items.find {
(it as? LibraryView.MyRelationView)?.sourceObject == libRelation.id
}
) {
libRelation.copy(
dependentData = if (this != null) {
DependentData.Model(item = this)
} else DependentData.None
)
}
} else {
libRelation
}
@ -124,7 +212,10 @@ class LibraryViewModel(
private val myTypesDelegate: MyTypesDelegate,
private val libraryTypesDelegate: LibraryTypesDelegate,
private val myRelationsDelegate: MyRelationsDelegate,
private val libraryRelationsDelegate: LibraryRelationsDelegate
private val libraryRelationsDelegate: LibraryRelationsDelegate,
private val addObjectToWorkspace: AddObjectToWorkspace,
private val removeObjectsFromWorkspace: RemoveObjectsFromWorkspace,
private val resourceManager: LibraryResourceManager
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
@ -132,7 +223,10 @@ class LibraryViewModel(
myTypesDelegate,
libraryTypesDelegate,
myRelationsDelegate,
libraryRelationsDelegate
libraryRelationsDelegate,
addObjectToWorkspace,
removeObjectsFromWorkspace,
resourceManager
) as T
}
}

View file

@ -12,9 +12,9 @@ import com.anytypeio.anytype.domain.workspace.WorkspaceManager
import com.anytypeio.anytype.presentation.dashboard.DEFAULT_KEYS
import com.anytypeio.anytype.presentation.library.LibraryListDelegate
import com.anytypeio.anytype.presentation.library.LibraryScreenState
import com.anytypeio.anytype.presentation.library.LibraryView
import com.anytypeio.anytype.presentation.library.QueryListenerMyTypes
import com.anytypeio.anytype.presentation.library.filterByQuery
import com.anytypeio.anytype.presentation.navigation.LibraryView
import com.anytypeio.anytype.presentation.objects.toLibraryViews
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants
import javax.inject.Inject

View file

@ -29,50 +29,3 @@ fun ObjectView.isContainsText(text: String): Boolean = title.contains(text, true
fun List<ObjectView>.filterBy(text: String): List<ObjectView> =
if (text.isNotEmpty()) this.filter { it.isContainsText(text) } else this
sealed interface LibraryView {
val id: Id
val name: String
class MyTypeView(
override val id: Id,
override val name: String,
val icon: ObjectIcon? = null,
val sourceObject: Id? = null,
val readOnly: Boolean = false
) : LibraryView
data class LibraryTypeView(
override val id: Id,
override val name: String,
val icon: ObjectIcon? = null,
val installed: Boolean = false,
) : LibraryView
class MyRelationView(
override val id: Id,
override val name: String,
val format: RelationFormat,
val sourceObject: Id? = null,
val readOnly: Boolean = false
) : LibraryView
data class LibraryRelationView(
override val id: Id,
override val name: String,
val format: RelationFormat,
val installed: Boolean = false,
) : LibraryView
class UnknownView(
override val id: Id = "",
override val name: String = "",
) : LibraryView
class CreateNewTypeView(
override val id: Id = "",
override val name: String = ""
) : LibraryView
}

View file

@ -9,7 +9,7 @@ import com.anytypeio.anytype.core_models.Relations.SOURCE_OBJECT
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.presentation.linking.LinkToItemView
import com.anytypeio.anytype.presentation.navigation.DefaultObjectView
import com.anytypeio.anytype.presentation.navigation.LibraryView
import com.anytypeio.anytype.presentation.library.LibraryView
import com.anytypeio.anytype.presentation.relations.RelationValueView
import com.anytypeio.anytype.presentation.sets.filter.CreateFilterView
import timber.log.Timber
@ -72,7 +72,6 @@ fun List<ObjectWrapper.Basic>.toLibraryViews(
layout = obj.getProperLayout(),
builder = urlBuilder
),
installed = false,
)
}
ObjectTypeIds.OBJECT_TYPE -> {

View file

@ -1,3 +1,10 @@
<resources>
<string name="app_name">presentation</string>
<string name="library_type_added">Type `%1$s` added to your library"</string>
<string name="library_type_removed">Type `%1$s` removed from your library"</string>
<string name="library_relation_added">Relation `%1$s` added to your library"</string>
<string name="library_relation_removed">Relation `%1$s` removed from your library"</string>
<string name="library_something_went_wrong">Something went wrong. Please, try again later.</string>
</resources>