From 8d38f94b13cfb290851b76f82cb61f91d2ce4c1c Mon Sep 17 00:00:00 2001 From: Evgenii Kozlov Date: Fri, 30 Dec 2022 15:09:22 +0300 Subject: [PATCH] DROID-735 Widgets | Enhancement | Foundations + basic API (#2792) --- .../anytype/di/common/ComponentManager.kt | 5 + .../anytype/di/feature/home/HomescreenDI.kt | 99 +++++++++++++++++ .../anytype/di/main/MainComponent.kt | 2 + .../anytypeio/anytype/ui/home/HomeFragment.kt | 52 +++++++++ app/src/main/res/layout/fragment_home.xml | 13 +++ app/src/main/res/navigation/graph.xml | 7 ++ .../anytypeio/anytype/core_models/Block.kt | 8 ++ .../anytypeio/anytype/core_models/Config.kt | 3 +- .../auth/repo/block/BlockDataRepository.kt | 5 + .../data/auth/repo/block/BlockDataStore.kt | 2 + .../data/auth/repo/block/BlockRemote.kt | 2 + .../auth/repo/block/BlockRemoteDataStore.kt | 5 + .../domain/block/repo/BlockRepository.kt | 5 + .../ObjectSearchSubscriptionContainer.kt | 19 +++- .../SearchObjectsByIdWithSubscription.kt | 8 +- .../anytype/domain/widgets/CreateWidget.kt | 24 +++++ .../anytype/middleware/auth/AuthMappers.kt | 6 +- .../middleware/block/BlockMiddleware.kt | 5 + .../middleware/interactor/Middleware.kt | 20 ++++ .../anytype/middleware/mappers/Alias.kt | 3 + .../middleware/mappers/ToCoreModelMappers.kt | 25 ++++- .../middleware/service/MiddlewareService.kt | 7 ++ .../MiddlewareServiceImplementation.kt | 13 +++ .../presentation/home/HomeViewModel.kt | 102 ++++++++++++++++++ .../presentation/widgets/WidgetView.kt | 10 ++ .../com/anytypeio/anytype/core_models/Auth.kt | 6 +- 26 files changed, 441 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/com/anytypeio/anytype/di/feature/home/HomescreenDI.kt create mode 100644 app/src/main/java/com/anytypeio/anytype/ui/home/HomeFragment.kt create mode 100644 app/src/main/res/layout/fragment_home.xml create mode 100644 domain/src/main/java/com/anytypeio/anytype/domain/widgets/CreateWidget.kt create mode 100644 presentation/src/main/java/com/anytypeio/anytype/presentation/home/HomeViewModel.kt create mode 100644 presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/WidgetView.kt diff --git a/app/src/main/java/com/anytypeio/anytype/di/common/ComponentManager.kt b/app/src/main/java/com/anytypeio/anytype/di/common/ComponentManager.kt index eb27b79fa4..08dc0ecf5d 100644 --- a/app/src/main/java/com/anytypeio/anytype/di/common/ComponentManager.kt +++ b/app/src/main/java/com/anytypeio/anytype/di/common/ComponentManager.kt @@ -63,6 +63,7 @@ import com.anytypeio.anytype.di.feature.ViewerSortByModule import com.anytypeio.anytype.di.feature.ViewerSortModule import com.anytypeio.anytype.di.feature.auth.DeletedAccountModule import com.anytypeio.anytype.di.feature.cover.UnsplashModule +import com.anytypeio.anytype.di.feature.home.HomescreenModule import com.anytypeio.anytype.di.feature.relations.LimitObjectTypeModule import com.anytypeio.anytype.di.feature.relations.RelationAddToDataViewModule import com.anytypeio.anytype.di.feature.relations.RelationAddToObjectModule @@ -176,6 +177,10 @@ class ComponentManager( .build() } + val homescreenComponent = Component { + main.homescreenComponentBuilder().module(HomescreenModule).build() + } + val wallpaperSelectComponent = Component { main .wallpaperSelectComponent() diff --git a/app/src/main/java/com/anytypeio/anytype/di/feature/home/HomescreenDI.kt b/app/src/main/java/com/anytypeio/anytype/di/feature/home/HomescreenDI.kt new file mode 100644 index 0000000000..15c9171a3a --- /dev/null +++ b/app/src/main/java/com/anytypeio/anytype/di/feature/home/HomescreenDI.kt @@ -0,0 +1,99 @@ +package com.anytypeio.anytype.di.feature.home + +import com.anytypeio.anytype.core_utils.di.scope.PerScreen +import com.anytypeio.anytype.domain.`object`.OpenObject +import com.anytypeio.anytype.domain.auth.repo.AuthRepository +import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers +import com.anytypeio.anytype.domain.block.repo.BlockRepository +import com.anytypeio.anytype.domain.config.ConfigStorage +import com.anytypeio.anytype.domain.objects.ObjectStore +import com.anytypeio.anytype.domain.search.ObjectSearchSubscriptionContainer +import com.anytypeio.anytype.domain.search.SubscriptionEventChannel +import com.anytypeio.anytype.domain.widgets.CreateWidget +import com.anytypeio.anytype.presentation.home.HomeViewModel +import com.anytypeio.anytype.ui.home.HomeFragment +import dagger.Module +import dagger.Provides +import dagger.Subcomponent +import kotlinx.coroutines.Dispatchers + +@Subcomponent( + modules = [HomescreenModule::class] +) +@PerScreen +interface HomescreenSubComponent { + @Subcomponent.Builder + interface Builder { + fun module(module: HomescreenModule): Builder + fun build(): HomescreenSubComponent + } + + fun inject(fragment: HomeFragment) +} + +@Module +object HomescreenModule { + + @JvmStatic + @Provides + @PerScreen + fun vmFactory( + openObject: OpenObject, + createWidget: CreateWidget, + configStorage: ConfigStorage, + objectSearchSubscriptionContainer: ObjectSearchSubscriptionContainer + ): HomeViewModel.Factory = HomeViewModel.Factory( + openObject = openObject, + createWidget = createWidget, + configStorage = configStorage, + objectSearchSubscriptionContainer = objectSearchSubscriptionContainer + ) + + @JvmStatic + @Provides + @PerScreen + fun openObject( + repo: BlockRepository, + auth: AuthRepository, + dispatchers: AppCoroutineDispatchers + ): OpenObject = OpenObject( + repo = repo, + dispatchers = dispatchers, + auth = auth + ) + + @JvmStatic + @Provides + @PerScreen + fun createWidget( + repo: BlockRepository, + dispatchers: AppCoroutineDispatchers + ): CreateWidget = CreateWidget( + repo = repo, + dispatchers = dispatchers + ) + + @JvmStatic + @Provides + @PerScreen + fun objectSearchSubscriptionContainer( + repo: BlockRepository, + channel: SubscriptionEventChannel, + store: ObjectStore, + dispatchers: AppCoroutineDispatchers + ): ObjectSearchSubscriptionContainer = ObjectSearchSubscriptionContainer( + repo = repo, + channel = channel, + store = store, + dispatchers = dispatchers + ) + + @JvmStatic + @Provides + @PerScreen + fun dispatchers(): AppCoroutineDispatchers = AppCoroutineDispatchers( + io = Dispatchers.IO, + main = Dispatchers.Main, + computation = Dispatchers.Default + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/anytypeio/anytype/di/main/MainComponent.kt b/app/src/main/java/com/anytypeio/anytype/di/main/MainComponent.kt index 47b4e04dbf..5ee5fa8a20 100644 --- a/app/src/main/java/com/anytypeio/anytype/di/main/MainComponent.kt +++ b/app/src/main/java/com/anytypeio/anytype/di/main/MainComponent.kt @@ -21,6 +21,7 @@ import com.anytypeio.anytype.di.feature.OtherSettingsSubComponent import com.anytypeio.anytype.di.feature.PageNavigationSubComponent import com.anytypeio.anytype.di.feature.SplashSubComponent import com.anytypeio.anytype.di.feature.auth.DeletedAccountSubcomponent +import com.anytypeio.anytype.di.feature.home.HomescreenSubComponent import com.anytypeio.anytype.di.feature.settings.AboutAppSubComponent import com.anytypeio.anytype.di.feature.settings.AccountAndDataSubComponent import com.anytypeio.anytype.di.feature.settings.AppearanceDependencies @@ -58,6 +59,7 @@ interface MainComponent : AppearanceDependencies { fun splashComponentBuilder(): SplashSubComponent.Builder fun homeDashboardComponentBuilder(): HomeDashboardSubComponent.Builder + fun homescreenComponentBuilder(): HomescreenSubComponent.Builder fun editorComponentBuilder(): EditorSubComponent.Builder fun archiveComponentBuilder(): ArchiveSubComponent.Builder fun createBookmarkBuilder(): CreateBookmarkSubComponent.Builder diff --git a/app/src/main/java/com/anytypeio/anytype/ui/home/HomeFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/home/HomeFragment.kt new file mode 100644 index 0000000000..514e91a23b --- /dev/null +++ b/app/src/main/java/com/anytypeio/anytype/ui/home/HomeFragment.kt @@ -0,0 +1,52 @@ +package com.anytypeio.anytype.ui.home + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope +import com.anytypeio.anytype.R +import com.anytypeio.anytype.databinding.FragmentHomeBinding +import com.anytypeio.anytype.di.common.componentManager +import com.anytypeio.anytype.presentation.home.HomeViewModel +import com.anytypeio.anytype.ui.base.NavigationFragment +import kotlinx.coroutines.launch +import javax.inject.Inject + +class HomeFragment : NavigationFragment(R.layout.fragment_home) { + + @Inject + lateinit var factory: HomeViewModel.Factory + + private val vm by viewModels { factory } + + override fun onStart() { + super.onStart() + vm.onStart() + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + lifecycleScope.launch { + vm.msg.collect { + binding.tvMsg.text = it + } + } + } + + override fun injectDependencies() { + componentManager().homescreenComponent.get().inject(this) + } + + override fun releaseDependencies() { + componentManager().homescreenComponent.release() + } + + override fun inflateBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): FragmentHomeBinding = FragmentHomeBinding.inflate( + inflater, container, false + ) +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000000..b6f325a906 --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/graph.xml b/app/src/main/res/navigation/graph.xml index 7a2af13691..1fb41143ae 100644 --- a/app/src/main/res/navigation/graph.xml +++ b/app/src/main/res/navigation/graph.xml @@ -147,6 +147,13 @@ app:destination="@id/createSetScreen" /> + + + ): List suspend fun createObject(command: Command.CreateObject): CreateObjectResult + + suspend fun createWidget(ctx: Id, source: Id): Payload } \ No newline at end of file diff --git a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemoteDataStore.kt b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemoteDataStore.kt index 53f733b0bb..377036c856 100644 --- a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemoteDataStore.kt +++ b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/block/BlockRemoteDataStore.kt @@ -626,4 +626,9 @@ class BlockRemoteDataStore(private val remote: BlockRemote) : BlockDataStore { ): CreateObjectResult { return remote.createObject(command) } + + override suspend fun createWidget(ctx: Id, source: Id): Payload = remote.createWidget( + ctx = ctx, + source = source + ) } \ No newline at end of file diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/block/repo/BlockRepository.kt b/domain/src/main/java/com/anytypeio/anytype/domain/block/repo/BlockRepository.kt index 9bc2ec57c0..0da2665815 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/block/repo/BlockRepository.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/block/repo/BlockRepository.kt @@ -350,4 +350,9 @@ interface BlockRepository { ): Payload suspend fun addObjectToWorkspace(objects: List) : List + + suspend fun createWidget( + ctx: Id, + source: Id + ): Payload } \ No newline at end of file diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/search/ObjectSearchSubscriptionContainer.kt b/domain/src/main/java/com/anytypeio/anytype/domain/search/ObjectSearchSubscriptionContainer.kt index 54333359fe..61614df541 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/search/ObjectSearchSubscriptionContainer.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/search/ObjectSearchSubscriptionContainer.kt @@ -3,6 +3,8 @@ package com.anytypeio.anytype.domain.search import com.anytypeio.anytype.core_models.DVFilter import com.anytypeio.anytype.core_models.DVSort import com.anytypeio.anytype.core_models.Id +import com.anytypeio.anytype.core_models.Key +import com.anytypeio.anytype.core_models.ObjectWrapper import com.anytypeio.anytype.core_models.Subscription import com.anytypeio.anytype.core_models.SubscriptionEvent import com.anytypeio.anytype.domain.`object`.move @@ -34,7 +36,6 @@ class ObjectSearchSubscriptionContainer( keys: List ): Flow { return flow { - val initial = repo.searchObjectsWithSubscription( subscription = subscription, sorts = sorts, @@ -139,7 +140,19 @@ class ObjectSearchSubscriptionContainer( result } ) - } - .flowOn(dispatchers.io) + }.flowOn(dispatchers.io) + } + + fun observe( + subscription: Id, + targets: List, + keys: List + ): Flow> = flow { + val initial = repo.searchObjectsByIdWithSubscription( + subscription = subscription, + ids = targets, + keys = keys + ) + emit(initial.results) } } \ No newline at end of file diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/search/SearchObjectsByIdWithSubscription.kt b/domain/src/main/java/com/anytypeio/anytype/domain/search/SearchObjectsByIdWithSubscription.kt index 2b47b862bd..6d1310b355 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/search/SearchObjectsByIdWithSubscription.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/search/SearchObjectsByIdWithSubscription.kt @@ -2,15 +2,15 @@ package com.anytypeio.anytype.domain.search import com.anytypeio.anytype.core_models.Id import com.anytypeio.anytype.core_models.SearchResult -import com.anytypeio.anytype.domain.base.BaseUseCase +import com.anytypeio.anytype.domain.base.ResultatInteractor import com.anytypeio.anytype.domain.block.repo.BlockRepository class SearchObjectsByIdWithSubscription( private val repo: BlockRepository -) : BaseUseCase() { +) : ResultatInteractor() { - override suspend fun run(params: Params) = safe { - repo.searchObjectsByIdWithSubscription( + override suspend fun execute(params: Params): SearchResult { + return repo.searchObjectsByIdWithSubscription( subscription = params.subscription, ids = params.ids, keys = params.keys diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/widgets/CreateWidget.kt b/domain/src/main/java/com/anytypeio/anytype/domain/widgets/CreateWidget.kt new file mode 100644 index 0000000000..952358ad44 --- /dev/null +++ b/domain/src/main/java/com/anytypeio/anytype/domain/widgets/CreateWidget.kt @@ -0,0 +1,24 @@ +package com.anytypeio.anytype.domain.widgets + +import com.anytypeio.anytype.core_models.Id +import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers +import com.anytypeio.anytype.domain.base.ResultatInteractor +import com.anytypeio.anytype.domain.block.repo.BlockRepository + +class CreateWidget( + private val dispatchers: AppCoroutineDispatchers, + private val repo: BlockRepository +) : ResultatInteractor() { + + override suspend fun execute(params: Params) { + repo.createWidget( + ctx = params.ctx, + source = params.source + ) + } + + data class Params( + val ctx: Id, + val source: Id + ) +} \ No newline at end of file diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/auth/AuthMappers.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/auth/AuthMappers.kt index 3e8210ff7a..9f683bdb81 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/auth/AuthMappers.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/auth/AuthMappers.kt @@ -34,7 +34,8 @@ fun Rpc.Account.Create.Response.toAccountSetup() : AccountSetup { home = info.homeObjectId, profile = info.profileObjectId, gateway = info.gatewayUrl, - workspace = info.accountSpaceId + workspace = info.accountSpaceId, + widgets = info.widgetsId ), status = status.core() ) @@ -67,7 +68,8 @@ fun Rpc.Account.Select.Response.toAccountSetup(): AccountSetup { home = info.homeObjectId, profile = info.profileObjectId, gateway = info.gatewayUrl, - workspace = info.accountSpaceId + workspace = info.accountSpaceId, + widgets = info.widgetsId ), status = status.core() ) diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/block/BlockMiddleware.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/block/BlockMiddleware.kt index b2d8cf3c7e..10cec12641 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/block/BlockMiddleware.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/block/BlockMiddleware.kt @@ -663,4 +663,9 @@ class BlockMiddleware( override suspend fun createBlockLinkWithObject( command: Command.CreateBlockLinkWithObject ): CreateBlockLinkWithObjectResult = middleware.blockLinkCreateWithObject(command) + + override suspend fun createWidget(ctx: Id, source: Id): Payload = middleware.createWidgetBlock( + ctx = ctx, + source = source + ) } \ No newline at end of file diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/Middleware.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/Middleware.kt index 7d25520cf7..31c7b1baf5 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/Middleware.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/interactor/Middleware.kt @@ -1810,6 +1810,26 @@ class Middleware( return response.objectIds } + @Throws(Exception::class) + fun createWidgetBlock( + ctx: Id, + source: Id + ): Payload { + val request = Rpc.Block.CreateWidget.Request( + contextId = ctx, + widgetLayout = Block.Content.Widget.Layout.Tree, + block = Block( + link = Block.Content.Link( + targetBlockId = source + ) + ) + ) + if (BuildConfig.DEBUG) logRequest(request) + val response = service.blockCreateWidget(request) + if (BuildConfig.DEBUG) logResponse(response) + return response.event.toPayload() + } + private fun logRequest(any: Any) { logger.logRequest(any) } diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/Alias.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/Alias.kt index d2dc67734c..da75f5909f 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/Alias.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/Alias.kt @@ -56,3 +56,6 @@ typealias MRelationOption = anytype.model.Relation.Option typealias MObjectRestriction = anytype.model.Restrictions.ObjectRestriction typealias MDVRestrictions = anytype.model.Restrictions.DataviewRestrictions typealias MDVRestriction = anytype.model.Restrictions.DataviewRestriction + +typealias MWidget = anytype.model.Block.Content.Widget +typealias MWidgetLayout = anytype.model.Block.Content.Widget.Layout diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/ToCoreModelMappers.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/ToCoreModelMappers.kt index 3fa99410fa..cd2e5e7d5b 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/ToCoreModelMappers.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/mappers/ToCoreModelMappers.kt @@ -23,7 +23,7 @@ fun ResponseEvent?.toPayload(): Payload { ) } -fun MObjectView.toPayload() : Payload { +fun MObjectView.toPayload(): Payload { val type = type.toCoreModel() return Payload( context = rootId, @@ -48,7 +48,7 @@ fun MObjectView.toPayload() : Payload { ) } -fun MObjectView.toCore() : ObjectView { +fun MObjectView.toCore(): ObjectView { val type = type.toCoreModel() return ObjectView( root = rootId, @@ -211,6 +211,15 @@ fun List.toCoreModels( backgroundColor = block.backgroundColor ) } + block.widget != null -> { + Block( + id = block.id, + fields = block.toCoreModelsFields(), + children = block.childrenIds, + content = block.toCoreWidget(), + backgroundColor = block.backgroundColor + ) + } else -> { Block( id = block.id, @@ -330,7 +339,7 @@ fun MBlock.toCoreModelsBookmark(): Block.Content.Bookmark { ) } -fun MBookmarkState.toCoreModelsBookmarkState() : Block.Content.Bookmark.State { +fun MBookmarkState.toCoreModelsBookmarkState(): Block.Content.Bookmark.State { return when (this) { MBookmarkState.Empty -> Block.Content.Bookmark.State.EMPTY MBookmarkState.Fetching -> Block.Content.Bookmark.State.FETCHING @@ -363,6 +372,16 @@ fun MBlock.toCoreModelsTableRowBlock(): Block.Content.TableRow { ) } +fun MBlock.toCoreWidget(): Block.Content.Widget { + val content = checkNotNull(widget) + return Block.Content.Widget( + layout = when (content.layout) { + MWidgetLayout.Link -> Block.Content.Widget.Layout.LINK + MWidgetLayout.Tree -> Block.Content.Widget.Layout.TREE + } + ) +} + fun MBFileState.toCoreModels(): Block.Content.File.State = when (this) { MBFileState.Empty -> Block.Content.File.State.EMPTY MBFileState.Uploading -> Block.Content.File.State.UPLOADING diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareService.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareService.kt index 6e60e1c746..5fc8d7991e 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareService.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareService.kt @@ -370,6 +370,13 @@ interface MiddlewareService { //endregion + //region WIDGETS commands + + @Throws(Exception::class) + fun blockCreateWidget(request: Rpc.Block.CreateWidget.Request): Rpc.Block.CreateWidget.Response + + //endregion + //region WORKSPACE @Throws(Exception::class) diff --git a/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareServiceImplementation.kt b/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareServiceImplementation.kt index 7cec0641bb..dacf14e567 100644 --- a/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareServiceImplementation.kt +++ b/middleware/src/main/java/com/anytypeio/anytype/middleware/service/MiddlewareServiceImplementation.kt @@ -149,6 +149,19 @@ class MiddlewareServiceImplementation @Inject constructor( } } + override fun blockCreateWidget(request: Rpc.Block.CreateWidget.Request): Rpc.Block.CreateWidget.Response { + val encoded = Service.blockCreateWidget( + Rpc.Block.CreateWidget.Request.ADAPTER.encode(request) + ) + val response = Rpc.Block.CreateWidget.Response.ADAPTER.decode(encoded) + val error = response.error + if (error != null && error.code != Rpc.Block.CreateWidget.Response.Error.Code.NULL) { + throw Exception(error.description) + } else { + return response + } + } + override fun blockDataViewActiveSet(request: Rpc.BlockDataview.View.SetActive.Request): Rpc.BlockDataview.View.SetActive.Response { val encoded = Service.blockDataviewViewSetActive( Rpc.BlockDataview.View.SetActive.Request.ADAPTER.encode(request) diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/home/HomeViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/home/HomeViewModel.kt new file mode 100644 index 0000000000..97dfb603c7 --- /dev/null +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/home/HomeViewModel.kt @@ -0,0 +1,102 @@ +package com.anytypeio.anytype.presentation.home + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewModelScope +import com.anytypeio.anytype.core_models.Block +import com.anytypeio.anytype.core_models.Id +import com.anytypeio.anytype.core_models.ObjectView +import com.anytypeio.anytype.domain.`object`.OpenObject +import com.anytypeio.anytype.domain.base.Resultat +import com.anytypeio.anytype.domain.config.ConfigStorage +import com.anytypeio.anytype.domain.search.ObjectSearchSubscriptionContainer +import com.anytypeio.anytype.domain.widgets.CreateWidget +import com.anytypeio.anytype.presentation.common.BaseViewModel +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch +import timber.log.Timber + +class HomeViewModel( + private val configStorage: ConfigStorage, + private val openObject: OpenObject, + private val createWidget: CreateWidget, + private val objectSearchSubscriptionContainer: ObjectSearchSubscriptionContainer +) : BaseViewModel() { + + val msg = MutableStateFlow("") + + val obj = MutableSharedFlow() + + init { + + obj.map { + it.blocks.mapNotNull { b -> + val content = b.content + if (content is Block.Content.Link) { + + } + null + } + } + + viewModelScope.launch { + val config = configStorage.get() + openObject(config.widgets).collect { result -> + when (result) { + is Resultat.Failure -> { + Timber.e(result.exception, "Error while opening object.") + } + is Resultat.Loading -> { + // Do nothing. + } + is Resultat.Success -> { + Timber.d("Blocks on start: ${result.value.blocks}") + obj.emit(result.value) + } + } + } + } + +// proceedWithCreatingWidget() + } + + private fun proceedWithCreatingWidget() { + viewModelScope.launch { + val config = configStorage.get() + createWidget( + CreateWidget.Params( + ctx = config.widgets, + source = "bafybasflgzee6ksloqb3bq5edtnfsithqvoymakywjocomehqbfs7gtc" + ) + ).collect { s -> + Timber.d("Status whule creating widget: $s") + } + } + } + + fun onStart() { + Timber.d("onStart") + } + + class Factory( + private val configStorage: ConfigStorage, + private val openObject: OpenObject, + private val createWidget: CreateWidget, + private val objectSearchSubscriptionContainer: ObjectSearchSubscriptionContainer + ) : ViewModelProvider.Factory { + @Suppress("UNCHECKED_CAST") + override fun create(modelClass: Class): T = HomeViewModel( + configStorage = configStorage, + openObject = openObject, + createWidget = createWidget, + objectSearchSubscriptionContainer = objectSearchSubscriptionContainer + ) as T + } +} + +data class Widget( + val id: Id, + val source: Id, +) \ No newline at end of file diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/WidgetView.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/WidgetView.kt new file mode 100644 index 0000000000..710e6df9e7 --- /dev/null +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/WidgetView.kt @@ -0,0 +1,10 @@ +package com.anytypeio.anytype.presentation.widgets + +import com.anytypeio.anytype.core_models.Id + +sealed class WidgetView { + data class Default( + val id: Id, + val elements: List + ) : WidgetView() +} \ No newline at end of file diff --git a/test/core-models-stub/src/main/java/com/anytypeio/anytype/core_models/Auth.kt b/test/core-models-stub/src/main/java/com/anytypeio/anytype/core_models/Auth.kt index c9d51054dc..17c759e0a6 100644 --- a/test/core-models-stub/src/main/java/com/anytypeio/anytype/core_models/Auth.kt +++ b/test/core-models-stub/src/main/java/com/anytypeio/anytype/core_models/Auth.kt @@ -30,12 +30,14 @@ fun StubConfig( home: Id = MockDataFactory.randomUuid(), profile: Id = MockDataFactory.randomUuid(), gateway: Url = MockDataFactory.randomUuid(), - workspace: Id = MockDataFactory.randomUuid() + workspace: Id = MockDataFactory.randomUuid(), + widgets: Id = MockDataFactory.randomUuid() ) : Config = Config( home = home, profile = profile, gateway = gateway, - workspace = workspace + workspace = workspace, + widgets = widgets ) fun StubFeatureConfig(