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

Object | Add-to-favorites & Remove-from-favorites (#1636)

This commit is contained in:
Evgenii Kozlov 2021-07-14 11:11:11 +03:00 committed by GitHub
parent 5d1f7c3ffe
commit 2517367f5a
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 318 additions and 99 deletions

View file

@ -5,7 +5,7 @@ import com.anytypeio.anytype.domain.block.interactor.CreateLinkToObject
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.config.GetConfig
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.page.navigation.GetPageInfoWithLinks
import com.anytypeio.anytype.domain.page.navigation.GetObjectInfoWithLinks
import com.anytypeio.anytype.presentation.linking.LinkToObjectViewModelFactory
import com.anytypeio.anytype.ui.linking.LinkToObjectFragment
import dagger.Module
@ -35,19 +35,19 @@ object LinkToObjectModule {
@Provides
fun provideGetPageInfoWithLinks(
repo: BlockRepository
): GetPageInfoWithLinks = GetPageInfoWithLinks(repo = repo)
): GetObjectInfoWithLinks = GetObjectInfoWithLinks(repo = repo)
@JvmStatic
@PerScreen
@Provides
fun provideLinkToObjectViewModelFactory(
urlBuilder: UrlBuilder,
getPageInfoWithLinks: GetPageInfoWithLinks,
getObjectInfoWithLinks: GetObjectInfoWithLinks,
createLinkToObject: CreateLinkToObject,
getConfig: GetConfig
): LinkToObjectViewModelFactory = LinkToObjectViewModelFactory(
urlBuilder = urlBuilder,
getPageInfoWithLinks = getPageInfoWithLinks,
getObjectInfoWithLinks = getObjectInfoWithLinks,
createLinkToObject = createLinkToObject,
getConfig = getConfig
)

View file

@ -5,7 +5,7 @@ import com.anytypeio.anytype.domain.block.interactor.Move
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.config.GetConfig
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.page.navigation.GetPageInfoWithLinks
import com.anytypeio.anytype.domain.page.navigation.GetObjectInfoWithLinks
import com.anytypeio.anytype.presentation.moving.MoveToViewModelFactory
import com.anytypeio.anytype.ui.moving.MoveToFragment
import dagger.Module
@ -35,7 +35,7 @@ object MoveToModule {
@Provides
fun provideGetPageInfoWithLinks(
repo: BlockRepository
): GetPageInfoWithLinks = GetPageInfoWithLinks(repo = repo)
): GetObjectInfoWithLinks = GetObjectInfoWithLinks(repo = repo)
@JvmStatic
@PerScreen
@ -58,12 +58,12 @@ object MoveToModule {
@Provides
fun provideMoveToViewModelFactory(
urlBuilder: UrlBuilder,
getPageInfoWithLinks: GetPageInfoWithLinks,
getObjectInfoWithLinks: GetObjectInfoWithLinks,
getConfig: GetConfig,
move: Move
): MoveToViewModelFactory = MoveToViewModelFactory(
urlBuilder = urlBuilder,
getPageInfoWithLinks = getPageInfoWithLinks,
getObjectInfoWithLinks = getObjectInfoWithLinks,
getConfig = getConfig,
move = move
)

View file

@ -5,7 +5,7 @@ import com.anytypeio.anytype.core_utils.di.scope.PerScreen
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.config.GetConfig
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.page.navigation.GetPageInfoWithLinks
import com.anytypeio.anytype.domain.page.navigation.GetObjectInfoWithLinks
import com.anytypeio.anytype.presentation.navigation.PageNavigationViewModelFactory
import com.anytypeio.anytype.ui.navigation.PageNavigationFragment
import dagger.Module
@ -33,21 +33,21 @@ object PageNavigationModule {
@JvmStatic
@PerScreen
@Provides
fun provideGetPageInfoWithLinks(repo: BlockRepository): GetPageInfoWithLinks =
GetPageInfoWithLinks(repo = repo)
fun provideGetPageInfoWithLinks(repo: BlockRepository): GetObjectInfoWithLinks =
GetObjectInfoWithLinks(repo = repo)
@JvmStatic
@PerScreen
@Provides
fun provideNavigationViewModelFactory(
urlBuilder: UrlBuilder,
getPageInfoWithLinks: GetPageInfoWithLinks,
getObjectInfoWithLinks: GetObjectInfoWithLinks,
getConfig: GetConfig,
analytics: Analytics
): PageNavigationViewModelFactory =
PageNavigationViewModelFactory(
urlBuilder = urlBuilder,
getPageInfoWithLinks = getPageInfoWithLinks,
getObjectInfoWithLinks = getObjectInfoWithLinks,
getConfig = getConfig,
analytics = analytics
)

View file

@ -1,6 +1,10 @@
package com.anytypeio.anytype.di.feature
import com.anytypeio.anytype.core_utils.di.scope.PerDialog
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.dashboard.interactor.AddToFavorite
import com.anytypeio.anytype.domain.dashboard.interactor.CheckIsFavorite
import com.anytypeio.anytype.domain.dashboard.interactor.RemoveFromFavorite
import com.anytypeio.anytype.domain.page.ArchiveDocument
import com.anytypeio.anytype.presentation.`object`.ObjectMenuViewModel
import com.anytypeio.anytype.ui.page.sheets.ObjectMenuFragment
@ -27,8 +31,35 @@ object ObjectMenuModule {
@Provides
@PerDialog
fun provideViewModelFactory(
archiveDocument: ArchiveDocument
archiveDocument: ArchiveDocument,
addToFavorite: AddToFavorite,
removeFromFavorite: RemoveFromFavorite,
checkIsFavorite: CheckIsFavorite
): ObjectMenuViewModel.Factory = ObjectMenuViewModel.Factory(
archiveDocument = archiveDocument
archiveDocument = archiveDocument,
addToFavorite = addToFavorite,
removeFromFavorite = removeFromFavorite,
checkIsFavorite = checkIsFavorite
)
@JvmStatic
@Provides
@PerDialog
fun provideAddToFavoriteUseCase(
repo: BlockRepository
) : AddToFavorite = AddToFavorite(repo = repo)
@JvmStatic
@Provides
@PerDialog
fun provideRemoveFromFavoriteUseCase(
repo: BlockRepository
) : RemoveFromFavorite = RemoveFromFavorite(repo = repo)
@JvmStatic
@Provides
@PerDialog
fun provideCheckIsFavoriteUseCase(
repo: BlockRepository
) : CheckIsFavorite = CheckIsFavorite(repo = repo)
}

View file

@ -206,10 +206,15 @@ class ObjectMenuFragment : BaseBottomSheetFragment() {
}
}
override fun onStart() {
super.onStart()
vm.onStart(ctx)
}
override fun onResume() {
super.onResume()
with(lifecycleScope) {
subscribe(vm.actions) { actionAdapter.items = it }
subscribe(vm.actions) { actionAdapter.submitList(it) }
subscribe(vm.toasts) { toast(it) }
subscribe(vm.isDismissed) { isDismissed -> if (isDismissed) dismiss() }
}

View file

@ -137,15 +137,21 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/optionHistory" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvActions"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="16dp"
<FrameLayout
android:id="@+id/rvContainer"
android:layout_width="match_parent"
android:layout_height="108dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/divider5" />
app:layout_constraintTop_toBottomOf="@+id/divider5">
<androidx.recyclerview.widget.RecyclerView
android:layout_gravity="center_vertical"
android:id="@+id/rvActions"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -14,10 +14,10 @@ data class DocumentInfo(
val smartBlockType: SmartBlockType
)
data class PageLinks(val inbound: List<DocumentInfo>, val outbound: List<DocumentInfo>)
data class ObjectLinks(val inbound: List<DocumentInfo>, val outbound: List<DocumentInfo>)
data class PageInfoWithLinks(
data class ObjectInfoWithLinks(
val id: String,
val documentInfo: DocumentInfo,
val links: PageLinks
val links: ObjectLinks
)

View file

@ -2,6 +2,8 @@ package com.anytypeio.anytype.core_ui.features.`object`
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.anytypeio.anytype.core_ui.R
import com.anytypeio.anytype.presentation.`object`.ObjectAction
@ -9,23 +11,16 @@ import kotlinx.android.synthetic.main.item_object_menu_action.view.*
class ObjectActionAdapter(
val onObjectActionClicked: (ObjectAction) -> Unit
) : RecyclerView.Adapter<ObjectActionAdapter.ViewHolder>() {
var items: List<ObjectAction> = emptyList()
set(value) {
field = value
notifyDataSetChanged()
}
) : ListAdapter<ObjectAction, ObjectActionAdapter.ViewHolder>(Differ) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(parent).apply {
itemView.setOnClickListener {
itemView.btnContainer.setOnClickListener {
val pos = bindingAdapterPosition
if (pos != RecyclerView.NO_POSITION)
onObjectActionClicked(items[pos])
onObjectActionClicked(getItem(pos))
}
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bind(items[position])
override fun getItemCount(): Int = items.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.bind(getItem(position))
class ViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder(
LayoutInflater.from(parent.context).inflate(
@ -42,6 +37,10 @@ class ObjectActionAdapter(
ivActionIcon.setImageResource(R.drawable.ic_object_action_add_to_favorites)
tvActionTitle.setText(R.string.favourite)
}
ObjectAction.REMOVE_FROM_FAVOURITE -> {
ivActionIcon.setImageResource(R.drawable.ic_object_action_add_to_favorites)
tvActionTitle.setText(R.string.unfavorite)
}
ObjectAction.SEARCH_ON_PAGE -> {
ivActionIcon.setImageResource(R.drawable.ic_object_action_search)
tvActionTitle.setText(R.string.search)
@ -50,8 +49,20 @@ class ObjectActionAdapter(
ivActionIcon.setImageResource(R.drawable.ic_object_action_template)
tvActionTitle.setText(R.string.template)
}
ObjectAction.MOVE_TO -> TODO()
else -> TODO()
}
}
}
object Differ : DiffUtil.ItemCallback<ObjectAction>() {
override fun areItemsTheSame(
oldItem: ObjectAction,
newItem: ObjectAction
): Boolean = oldItem.name == newItem.name
override fun areContentsTheSame(
oldItem: ObjectAction,
newItem: ObjectAction
): Boolean = oldItem == newItem
}
}

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/white">
<item>
<shape android:shape="rectangle">
<corners android:radius="10dp" />
<solid android:color="#F3F2EC" />
</shape>
</item>
</ripple>

View file

@ -6,9 +6,10 @@
android:orientation="vertical">
<FrameLayout
android:id="@+id/btnContainer"
android:layout_width="52dp"
android:layout_height="52dp"
android:background="@drawable/rectangle_object_menu_action">
android:background="@drawable/rectangle_object_menu_action_ripple">
<ImageView
android:id="@+id/ivActionIcon"

View file

@ -393,5 +393,7 @@
<string name="name_is_required">Name is required</string>
<string name="favourite">Favorite</string>
<string name="template">Template</string>
<string name="restore">Restore</string>
<string name="unfavorite">Unfavorite</string>
</resources>

View file

@ -199,8 +199,9 @@ class BlockDataRepository(
command: Command.UploadFile
): Hash = factory.remote.uploadFile(command)
override suspend fun getPageInfoWithLinks(pageId: String): PageInfoWithLinks =
factory.remote.getPageInfoWithLinks(pageId)
override suspend fun getObjectInfoWithLinks(
pageId: String
): ObjectInfoWithLinks = factory.remote.getObjectInfoWithLinks(pageId)
override suspend fun getListPages(): List<DocumentInfo> = factory.remote.getListPages()

View file

@ -50,7 +50,7 @@ interface BlockDataStore {
suspend fun uploadFile(command: Command.UploadFile): String
suspend fun getPageInfoWithLinks(pageId: String): PageInfoWithLinks
suspend fun getObjectInfoWithLinks(pageId: String): ObjectInfoWithLinks
suspend fun getListPages(): List<DocumentInfo>

View file

@ -49,7 +49,7 @@ interface BlockRemote {
suspend fun uploadFile(command: Command.UploadFile): String
suspend fun getPageInfoWithLinks(pageId: String): PageInfoWithLinks
suspend fun getObjectInfoWithLinks(pageId: String): ObjectInfoWithLinks
suspend fun getListPages(): List<DocumentInfo>

View file

@ -153,8 +153,8 @@ class BlockRemoteDataStore(private val remote: BlockRemote) : BlockDataStore {
command: Command.UploadFile
): String = remote.uploadFile(command)
override suspend fun getPageInfoWithLinks(pageId: String): PageInfoWithLinks =
remote.getPageInfoWithLinks(pageId)
override suspend fun getObjectInfoWithLinks(pageId: String): ObjectInfoWithLinks =
remote.getObjectInfoWithLinks(pageId)
override suspend fun getListPages(): List<DocumentInfo> = remote.getListPages()

View file

@ -105,7 +105,7 @@ interface BlockRepository {
suspend fun copy(command: Command.Copy): Response.Clipboard.Copy
suspend fun paste(command: Command.Paste): Response.Clipboard.Paste
suspend fun getPageInfoWithLinks(pageId: String): PageInfoWithLinks
suspend fun getObjectInfoWithLinks(pageId: String): ObjectInfoWithLinks
suspend fun getListPages(): List<DocumentInfo>
suspend fun linkToObject(

View file

@ -0,0 +1,36 @@
package com.anytypeio.anytype.domain.dashboard.interactor
import com.anytypeio.anytype.core_models.*
import com.anytypeio.anytype.domain.base.BaseUseCase
import com.anytypeio.anytype.domain.block.repo.BlockRepository
/**
* Use-case for adding an object to favorite list.
*/
class AddToFavorite(
private val repo: BlockRepository
) : BaseUseCase<Pair<Id, Payload>, AddToFavorite.Params>() {
override suspend fun run(params: Params) = safe {
val config = repo.getConfig()
repo.create(
Command.Create(
context = config.home,
prototype = Block.Prototype.Link(target = params.target),
target = EMPTY_TARGET_ID,
position = Position.BOTTOM
)
)
}
/**
* @property [target] id of the object we need to add to favorites.
*/
class Params(
val target: Id
)
companion object {
const val EMPTY_TARGET_ID = ""
}
}

View file

@ -0,0 +1,24 @@
package com.anytypeio.anytype.domain.dashboard.interactor
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.domain.base.BaseUseCase
import com.anytypeio.anytype.domain.block.repo.BlockRepository
/**
* Use-case for checking whether an object is in the list of favorite objects on dashboard.
*/
class CheckIsFavorite(
private val repo: BlockRepository
) : BaseUseCase<Boolean, CheckIsFavorite.Params>() {
override suspend fun run(params: Params) = safe {
val config = repo.getConfig()
val info = repo.getObjectInfoWithLinks(config.home)
info.links.outbound.any { it.id == params.target }
}
/**
* @property [target] id of the object (smart block).
*/
class Params(val target: Id)
}

View file

@ -0,0 +1,27 @@
package com.anytypeio.anytype.domain.dashboard.interactor
import com.anytypeio.anytype.core_models.Command
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
@Deprecated("Currently does not work.")
class RemoveFromFavorite(
private val repo: BlockRepository
) : BaseUseCase<Payload, RemoveFromFavorite.Params>() {
override suspend fun run(params: Params) = safe {
val config = repo.getConfig()
val info = repo.getObjectInfoWithLinks(config.home)
val links = info.links.outbound.filter { it.id == params.target }
repo.unlink(
Command.Unlink(
context = config.home,
targets = links.map { it.id }
)
)
}
class Params(val target: Id)
}

View file

@ -1,16 +1,17 @@
package com.anytypeio.anytype.domain.page.navigation
import com.anytypeio.anytype.core_models.PageInfoWithLinks
import com.anytypeio.anytype.core_models.ObjectInfoWithLinks
import com.anytypeio.anytype.core_models.SmartBlockType
import com.anytypeio.anytype.domain.base.BaseUseCase
import com.anytypeio.anytype.domain.base.Either
import com.anytypeio.anytype.domain.block.repo.BlockRepository
class GetPageInfoWithLinks(private val repo: BlockRepository) :
BaseUseCase<GetPageInfoWithLinks.Response, GetPageInfoWithLinks.Params>() {
class GetObjectInfoWithLinks(
private val repo: BlockRepository
) : BaseUseCase<GetObjectInfoWithLinks.Response, GetObjectInfoWithLinks.Params>() {
override suspend fun run(params: Params): Either<Throwable, Response> = safe {
repo.getPageInfoWithLinks(
repo.getObjectInfoWithLinks(
pageId = params.pageId
).let {
Response(
@ -61,6 +62,6 @@ class GetPageInfoWithLinks(private val repo: BlockRepository) :
)
data class Response(
val pageInfoWithLinks: PageInfoWithLinks
val pageInfoWithLinks: ObjectInfoWithLinks
)
}

View file

@ -14,12 +14,12 @@ import org.mockito.Mock
import org.mockito.MockitoAnnotations
import kotlin.test.assertEquals
class GetPageInfoWithLinksTest {
class GetObjectInfoWithLinksTest {
@ExperimentalCoroutinesApi
@get:Rule
var rule = CoroutineTestRule()
lateinit var getPageInfoWithLinks: GetPageInfoWithLinks
lateinit var getObjectInfoWithLinks: GetObjectInfoWithLinks
@Mock
lateinit var repository: BlockRepository
@ -27,7 +27,7 @@ class GetPageInfoWithLinksTest {
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
getPageInfoWithLinks = GetPageInfoWithLinks(repository)
getObjectInfoWithLinks = GetObjectInfoWithLinks(repository)
}
@Test
@ -36,7 +36,7 @@ class GetPageInfoWithLinksTest {
val pageId = MockDataFactory.randomUuid()
repository.stub {
onBlocking { getPageInfoWithLinks(pageId) } doReturn PageInfoWithLinks(
onBlocking { getObjectInfoWithLinks(pageId) } doReturn ObjectInfoWithLinks(
id = pageId,
documentInfo = DocumentInfo(
id = pageId,
@ -45,7 +45,7 @@ class GetPageInfoWithLinksTest {
hasInboundLinks = true,
smartBlockType = SmartBlockType.PAGE
),
links = PageLinks(
links = ObjectLinks(
inbound = listOf(
DocumentInfo(
id = "12",
@ -98,7 +98,7 @@ class GetPageInfoWithLinksTest {
runBlocking {
getPageInfoWithLinks(GetPageInfoWithLinks.Params(pageId = pageId)).proceed(
getObjectInfoWithLinks(GetObjectInfoWithLinks.Params(pageId = pageId)).proceed(
failure = {},
success = { response ->
val outbound = response.pageInfoWithLinks.links.outbound

View file

@ -176,7 +176,7 @@ class BlockMiddleware(
command: Command.UploadFile
): String = middleware.uploadFile(command).hash
override suspend fun getPageInfoWithLinks(pageId: String): PageInfoWithLinks {
override suspend fun getObjectInfoWithLinks(pageId: String): ObjectInfoWithLinks {
return middleware.getObjectInfoWithLinks(pageId).toCoreModel()
}

View file

@ -449,17 +449,17 @@ fun MRelationOptionScope.scope(): Relation.OptionScope = when (this) {
}
// ---------------------- NAVIGATION & SEARCH ------------------------
fun ObjectInfoWithLinks.toCoreModel(): PageInfoWithLinks {
fun ObjectInfoWithLinks.toCoreModel(): com.anytypeio.anytype.core_models.ObjectInfoWithLinks {
val i = info
checkNotNull(i)
return PageInfoWithLinks(
return ObjectInfoWithLinks(
id = id,
links = links?.toCoreModel() ?: PageLinks(emptyList(), emptyList()),
links = links?.toCoreModel() ?: ObjectLinks(emptyList(), emptyList()),
documentInfo = i.toCoreModel()
)
}
fun ObjectLinksInfo.toCoreModel(): PageLinks = PageLinks(
fun ObjectLinksInfo.toCoreModel(): ObjectLinks = ObjectLinks(
inbound = inbound.map { it.toCoreModel() },
outbound = outbound.map { it.toCoreModel() }
)

View file

@ -2,16 +2,16 @@ package com.anytypeio.anytype.presentation.linking
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.Position
import com.anytypeio.anytype.core_utils.common.EventWrapper
import com.anytypeio.anytype.core_utils.ext.timber
import com.anytypeio.anytype.core_utils.ui.ViewState
import com.anytypeio.anytype.core_utils.ui.ViewStateViewModel
import com.anytypeio.anytype.domain.block.interactor.CreateLinkToObject
import com.anytypeio.anytype.core_models.Position
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.domain.config.GetConfig
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.page.navigation.GetPageInfoWithLinks
import com.anytypeio.anytype.domain.page.navigation.GetObjectInfoWithLinks
import com.anytypeio.anytype.presentation.mapper.toEmojiView
import com.anytypeio.anytype.presentation.mapper.toImageView
import com.anytypeio.anytype.presentation.mapper.toView
@ -24,7 +24,7 @@ import timber.log.Timber
class LinkToObjectViewModel(
private val urlBuilder: UrlBuilder,
private val getPageInfoWithLinks: GetPageInfoWithLinks,
private val getObjectInfoWithLinks: GetObjectInfoWithLinks,
private val createLinkToObject: CreateLinkToObject,
private val getConfig: GetConfig
) : ViewStateViewModel<ViewState<PageNavigationView>>(),
@ -57,7 +57,7 @@ class LinkToObjectViewModel(
private fun proceedWithGettingDocumentLinks(target: String) {
stateData.postValue(ViewState.Loading)
viewModelScope.launch {
getPageInfoWithLinks.invoke(GetPageInfoWithLinks.Params(pageId = target)).proceed(
getObjectInfoWithLinks.invoke(GetObjectInfoWithLinks.Params(pageId = target)).proceed(
failure = { error ->
error.timber()
stateData.postValue(ViewState.Error(error.message ?: "Unknown error"))

View file

@ -5,11 +5,11 @@ import androidx.lifecycle.ViewModelProvider
import com.anytypeio.anytype.domain.block.interactor.CreateLinkToObject
import com.anytypeio.anytype.domain.config.GetConfig
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.page.navigation.GetPageInfoWithLinks
import com.anytypeio.anytype.domain.page.navigation.GetObjectInfoWithLinks
class LinkToObjectViewModelFactory(
private val urlBuilder: UrlBuilder,
private val getPageInfoWithLinks: GetPageInfoWithLinks,
private val getObjectInfoWithLinks: GetObjectInfoWithLinks,
private val createLinkToObject: CreateLinkToObject,
private val getConfig: GetConfig
) : ViewModelProvider.Factory {
@ -18,7 +18,7 @@ class LinkToObjectViewModelFactory(
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return LinkToObjectViewModel(
urlBuilder = urlBuilder,
getPageInfoWithLinks = getPageInfoWithLinks,
getObjectInfoWithLinks = getObjectInfoWithLinks,
createLinkToObject = createLinkToObject,
getConfig = getConfig
) as T

View file

@ -2,16 +2,16 @@ package com.anytypeio.anytype.presentation.moving
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.Position
import com.anytypeio.anytype.core_utils.common.EventWrapper
import com.anytypeio.anytype.core_utils.ext.timber
import com.anytypeio.anytype.core_utils.ui.ViewState
import com.anytypeio.anytype.core_utils.ui.ViewStateViewModel
import com.anytypeio.anytype.domain.block.interactor.Move
import com.anytypeio.anytype.core_models.Position
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.domain.config.GetConfig
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.page.navigation.GetPageInfoWithLinks
import com.anytypeio.anytype.domain.page.navigation.GetObjectInfoWithLinks
import com.anytypeio.anytype.presentation.mapper.toEmojiView
import com.anytypeio.anytype.presentation.mapper.toImageView
import com.anytypeio.anytype.presentation.mapper.toView
@ -24,7 +24,7 @@ import timber.log.Timber
class MoveToViewModel(
private val urlBuilder: UrlBuilder,
private val getPageInfoWithLinks: GetPageInfoWithLinks,
private val getObjectInfoWithLinks: GetObjectInfoWithLinks,
private val getConfig: GetConfig,
private val move: Move
) : ViewStateViewModel<ViewState<PageNavigationView>>(),
@ -57,7 +57,7 @@ class MoveToViewModel(
fun proceedWithGettingDocumentLinks(target: String) {
stateData.postValue(ViewState.Loading)
viewModelScope.launch {
getPageInfoWithLinks.invoke(GetPageInfoWithLinks.Params(pageId = target)).proceed(
getObjectInfoWithLinks.invoke(GetObjectInfoWithLinks.Params(pageId = target)).proceed(
failure = { error ->
error.timber()
stateData.postValue(ViewState.Error(error.message ?: "Unknown error"))

View file

@ -5,11 +5,11 @@ import androidx.lifecycle.ViewModelProvider
import com.anytypeio.anytype.domain.block.interactor.Move
import com.anytypeio.anytype.domain.config.GetConfig
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.page.navigation.GetPageInfoWithLinks
import com.anytypeio.anytype.domain.page.navigation.GetObjectInfoWithLinks
class MoveToViewModelFactory(
private val urlBuilder: UrlBuilder,
private val getPageInfoWithLinks: GetPageInfoWithLinks,
private val getObjectInfoWithLinks: GetObjectInfoWithLinks,
private val getConfig: GetConfig,
private val move: Move
) : ViewModelProvider.Factory {
@ -18,7 +18,7 @@ class MoveToViewModelFactory(
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return MoveToViewModel(
urlBuilder = urlBuilder,
getPageInfoWithLinks = getPageInfoWithLinks,
getObjectInfoWithLinks = getObjectInfoWithLinks,
getConfig = getConfig,
move = move
) as T

View file

@ -11,7 +11,7 @@ import com.anytypeio.anytype.core_utils.ui.ViewState
import com.anytypeio.anytype.core_utils.ui.ViewStateViewModel
import com.anytypeio.anytype.domain.config.GetConfig
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.page.navigation.GetPageInfoWithLinks
import com.anytypeio.anytype.domain.page.navigation.GetObjectInfoWithLinks
import com.anytypeio.anytype.presentation.mapper.toEmojiView
import com.anytypeio.anytype.presentation.mapper.toImageView
import com.anytypeio.anytype.presentation.mapper.toView
@ -20,7 +20,7 @@ import timber.log.Timber
class PageNavigationViewModel(
private val urlBuilder: UrlBuilder,
private val getPageInfoWithLinks: GetPageInfoWithLinks,
private val getObjectInfoWithLinks: GetObjectInfoWithLinks,
private val getConfig: GetConfig,
private val analytics: Analytics
) :
@ -41,7 +41,7 @@ class PageNavigationViewModel(
fun onGetPageLinks(target: String) {
stateData.postValue(ViewState.Loading)
viewModelScope.launch {
getPageInfoWithLinks.invoke(GetPageInfoWithLinks.Params(pageId = target)).proceed(
getObjectInfoWithLinks.invoke(GetObjectInfoWithLinks.Params(pageId = target)).proceed(
failure = { error ->
error.timber()
stateData.postValue(ViewState.Error(error.message ?: "Unknown error"))

View file

@ -5,11 +5,11 @@ import androidx.lifecycle.ViewModelProvider
import com.anytypeio.anytype.analytics.base.Analytics
import com.anytypeio.anytype.domain.config.GetConfig
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.page.navigation.GetPageInfoWithLinks
import com.anytypeio.anytype.domain.page.navigation.GetObjectInfoWithLinks
class PageNavigationViewModelFactory(
private val urlBuilder: UrlBuilder,
private val getPageInfoWithLinks: GetPageInfoWithLinks,
private val getObjectInfoWithLinks: GetObjectInfoWithLinks,
private val getConfig: GetConfig,
private val analytics: Analytics
) : ViewModelProvider.Factory {
@ -18,7 +18,7 @@ class PageNavigationViewModelFactory(
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return PageNavigationViewModel(
urlBuilder = urlBuilder,
getPageInfoWithLinks = getPageInfoWithLinks,
getObjectInfoWithLinks = getObjectInfoWithLinks,
getConfig = getConfig,
analytics = analytics
) as T

View file

@ -4,6 +4,9 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.domain.dashboard.interactor.AddToFavorite
import com.anytypeio.anytype.domain.dashboard.interactor.CheckIsFavorite
import com.anytypeio.anytype.domain.dashboard.interactor.RemoveFromFavorite
import com.anytypeio.anytype.domain.page.ArchiveDocument
import com.anytypeio.anytype.presentation.common.BaseViewModel
import kotlinx.coroutines.flow.MutableStateFlow
@ -11,19 +14,41 @@ import kotlinx.coroutines.launch
import timber.log.Timber
class ObjectMenuViewModel(
private val archiveDocument: ArchiveDocument
private val archiveDocument: ArchiveDocument,
private val addToFavorite: AddToFavorite,
private val removeFromFavorite: RemoveFromFavorite,
private val checkIsFavorite: CheckIsFavorite
) : BaseViewModel() {
val isDismissed = MutableStateFlow(false)
val actions = MutableStateFlow(
listOf(
ObjectAction.DELETE,
ObjectAction.ADD_TO_FAVOURITE,
ObjectAction.SEARCH_ON_PAGE,
ObjectAction.USE_AS_TEMPLATE
)
)
val actions = MutableStateFlow(emptyList<ObjectAction>())
fun onStart(ctx: Id) {
viewModelScope.launch {
checkIsFavorite(CheckIsFavorite.Params(ctx)).process(
failure = {
Timber.e(it, "Error while checking is-favorite status for object")
},
success = { isFavorite ->
if (isFavorite)
actions.value = listOf(
ObjectAction.DELETE,
ObjectAction.REMOVE_FROM_FAVOURITE,
ObjectAction.SEARCH_ON_PAGE,
ObjectAction.USE_AS_TEMPLATE
)
else
actions.value = listOf(
ObjectAction.DELETE,
ObjectAction.ADD_TO_FAVOURITE,
ObjectAction.SEARCH_ON_PAGE,
ObjectAction.USE_AS_TEMPLATE
)
}
)
}
}
fun onActionClick(ctx: Id, action: ObjectAction) {
when (action) {
@ -33,10 +58,41 @@ class ObjectMenuViewModel(
ObjectAction.RESTORE -> {
proceedWithUpdatingArchivedStatus(ctx = ctx, isArchived = false)
}
ObjectAction.ADD_TO_FAVOURITE -> TODO()
ObjectAction.MOVE_TO -> TODO()
ObjectAction.SEARCH_ON_PAGE -> TODO()
ObjectAction.USE_AS_TEMPLATE -> TODO()
ObjectAction.ADD_TO_FAVOURITE -> {
viewModelScope.launch {
addToFavorite(
AddToFavorite.Params(
target = ctx
)
).process(
failure = { Timber.e(it, "Error while adding to favorites.") },
success = {
_toasts.emit(ADD_TO_FAVORITE_SUCCESS_MSG).also {
isDismissed.value = true
}
}
)
}
}
ObjectAction.REMOVE_FROM_FAVOURITE -> {
viewModelScope.launch {
removeFromFavorite(
RemoveFromFavorite.Params(
target = ctx
)
).process(
failure = { Timber.e(it, "Error while removing from favorite.") },
success = {
_toasts.emit(REMOVE_FROM_FAVORITE_SUCCESS_MSG).also {
isDismissed.value = true
}
}
)
}
}
else -> {
viewModelScope.launch { _toasts.emit("TODO") }
}
}
}
@ -67,11 +123,17 @@ class ObjectMenuViewModel(
@Suppress("UNCHECKED_CAST")
class Factory(
private val archiveDocument: ArchiveDocument
private val archiveDocument: ArchiveDocument,
private val addToFavorite: AddToFavorite,
private val removeFromFavorite: RemoveFromFavorite,
private val checkIsFavorite: CheckIsFavorite
) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return ObjectMenuViewModel(
archiveDocument = archiveDocument
archiveDocument = archiveDocument,
addToFavorite = addToFavorite,
removeFromFavorite = removeFromFavorite,
checkIsFavorite = checkIsFavorite
) as T
}
}
@ -81,5 +143,7 @@ class ObjectMenuViewModel(
const val RESTORE_OBJECT_SUCCESS_MSG = "Object restored!"
const val ARCHIVE_OBJECT_ERR_MSG =
"Error while changing is-archived status for this object. Please, try again later."
const val ADD_TO_FAVORITE_SUCCESS_MSG = "Object added to favorites."
const val REMOVE_FROM_FAVORITE_SUCCESS_MSG = "Object removed from favorites."
}
}