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

DROID-418 Tech | Enhancement | CreateObject commands refactoring (#2749)

* DROID-418 createDocument, legacy useCase

* DROID-418 objectCreate and blockLinkCreateWithObject commands refactoring

* DROID-418 data module refactoring

* DROID-418 refactoring, data + middleware modules

* DROID-418 legacy useCases

* DROID-418 update DI

* DROID-418 tests

* DROID-418 internal flags model

* DROID-418 command

* DROID-418 view model factorys

* DROID-418 viewmodels, update with new use cases

* DROID-418 mapping

* DROID-418 middleware, fixes

* DROID-418 createBlockLinkWithObject useCase

* DROID-418 createObject use case

* DROID-418 createObjectAsMentionOrLink useCase

* DROID-418 createDataViewObject refactoring

* DROID-418 create object tests, in progress

* DROID-418 after merge fixes

* DROID-418 add type

* DROID-418 createObject use case tests

* DROID-418 createObjectAsMentionOrLink tests

* DROID-418 createBlockLinkWithObject useCase tests

* DROID-418 ci

* DROID-418 ci off
This commit is contained in:
Konstantin Ivanov 2022-12-12 10:05:57 +01:00 committed by GitHub
parent 652d7dd224
commit a71e8ec55c
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 1384 additions and 1181 deletions

View file

@ -65,9 +65,8 @@ import com.anytypeio.anytype.domain.objects.DefaultStoreOfRelations
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.domain.page.CloseBlock
import com.anytypeio.anytype.domain.page.CreateDocument
import com.anytypeio.anytype.domain.page.CreateNewDocument
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreateObjectAsMentionOrLink
import com.anytypeio.anytype.domain.page.CreateBlockLinkWithObject
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.page.OpenPage
import com.anytypeio.anytype.domain.page.Redo
@ -112,15 +111,13 @@ import kotlinx.coroutines.test.StandardTestDispatcher
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.stub
open class EditorTestSetup {
lateinit var createObject: CreateObject
lateinit var createDocument: CreateDocument
lateinit var createBlockLinkWithObject: CreateBlockLinkWithObject
lateinit var downloadFile: DownloadFile
lateinit var undo: Undo
lateinit var redo: Redo
@ -184,13 +181,13 @@ open class EditorTestSetup {
lateinit var mergeBlocks: MergeBlocks
@Mock
lateinit var createNewObject: CreateNewObject
lateinit var createObject: CreateObject
lateinit var editorTemplateDelegate: EditorTemplateDelegate
lateinit var getTemplates: GetTemplates
lateinit var applyTemplate: ApplyTemplate
lateinit var createNewDocument: CreateNewDocument
lateinit var createObjectAsMentionOrLink: CreateObjectAsMentionOrLink
lateinit var interceptThreadStatus: InterceptThreadStatus
lateinit var setDocCoverImage: SetDocCoverImage
@ -288,7 +285,6 @@ open class EditorTestSetup {
)
splitBlock = SplitBlock(repo)
createDocument = CreateDocument(repo, documentEmojiIconProvider)
undo = Undo(repo)
redo = Redo(repo)
objectToSet = ConvertObjectToSet(repo)
@ -296,12 +292,12 @@ open class EditorTestSetup {
setupBookmark = SetupBookmark(repo)
updateAlignment = UpdateAlignment(repo)
uploadBlock = UploadBlock(repo)
createObject = CreateObject(repo, documentEmojiIconProvider)
createBlockLinkWithObject = CreateBlockLinkWithObject(repo, getTemplates)
setRelationKey = SetRelationKey(repo)
turnIntoDocument = TurnIntoDocument(repo)
updateFields = UpdateFields(repo)
setObjectType = SetObjectType(repo)
createNewDocument = CreateNewDocument(repo, documentEmojiIconProvider)
createObjectAsMentionOrLink = CreateObjectAsMentionOrLink(repo, getDefaultEditorType, getTemplates)
getSearchObjects = SearchObjects(repo)
interceptThreadStatus = InterceptThreadStatus(channel = threadStatusChannel)
downloadUnsplashImage = DownloadUnsplashImage(unsplashRepository)
@ -357,9 +353,8 @@ open class EditorTestSetup {
interceptEvents = interceptEvents,
updateLinkMarks = updateLinkMarks,
removeLinkMark = removeLinkMark,
createObject = createObject,
createBlockLinkWithObject = createBlockLinkWithObject,
documentEventReducer = DocumentExternalEventReducer(),
createDocument = createDocument,
urlBuilder = urlBuilder,
renderer = DefaultBlockViewRenderer(
urlBuilder = urlBuilder,
@ -413,7 +408,7 @@ open class EditorTestSetup {
clearBlockContent = clearBlockContent,
clearBlockStyle = clearBlockStyle
),
createNewDocument = createNewDocument,
createObjectAsMentionOrLink = createObjectAsMentionOrLink,
interceptThreadStatus = interceptThreadStatus,
analytics = analytics,
dispatcher = Dispatcher.Default(),
@ -429,7 +424,7 @@ open class EditorTestSetup {
setDocCoverImage = setDocCoverImage,
setDocImageIcon = setDocImageIcon,
editorTemplateDelegate = editorTemplateDelegate,
createNewObject = createNewObject,
createObject = createObject,
objectToSet = objectToSet,
storeOfRelations = storeOfRelations,
storeOfObjectTypes = storeOfObjectTypes,

View file

@ -33,7 +33,7 @@ import com.anytypeio.anytype.domain.objects.DefaultStoreOfRelations
import com.anytypeio.anytype.domain.objects.ObjectStore
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.domain.page.CloseBlock
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.CancelSearchSubscription
import com.anytypeio.anytype.domain.search.DataViewSubscriptionContainer
import com.anytypeio.anytype.domain.search.SubscriptionEventChannel
@ -107,7 +107,7 @@ abstract class TestObjectSetSetup {
lateinit var cancelSearchSubscription: CancelSearchSubscription
@Mock
lateinit var createNewObject: CreateNewObject
lateinit var createObject: CreateObject
private lateinit var getTemplates: GetTemplates
private lateinit var getDefaultEditorType: GetDefaultEditorType
@ -206,7 +206,7 @@ abstract class TestObjectSetSetup {
downloadUnsplashImage = downloadUnsplashImage,
setDocCoverImage = setDocCoverImage,
delegator = delegator,
createNewObject = createNewObject,
createObject = createObject,
setDataViewSource = setDataViewSource,
cancelSearchSubscription = cancelSearchSubscription,
paginator = paginator,

View file

@ -1,13 +1,18 @@
package com.anytypeio.anytype.di.feature
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.page.CreatePage
import com.anytypeio.anytype.domain.config.UserSettingsRepository
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.templates.GetTemplates
import com.anytypeio.anytype.presentation.objects.CreateObjectViewModel
import com.anytypeio.anytype.ui.editor.CreateObjectFragment
import dagger.Module
import dagger.Provides
import dagger.Subcomponent
import kotlinx.coroutines.Dispatchers
@Subcomponent(modules = [CreateObjectModule::class])
@PerScreen
@ -25,15 +30,42 @@ interface CreateObjectSubComponent {
@Module
object CreateObjectModule {
@JvmStatic
@Provides
@PerScreen
fun getCreateObject(
repo: BlockRepository,
getTemplates: GetTemplates,
getDefaultEditorType: GetDefaultEditorType
): CreateObject = CreateObject(
repo = repo,
getTemplates = getTemplates,
getDefaultEditorType = getDefaultEditorType
)
@JvmStatic
@PerScreen
@Provides
fun createPage(repo: BlockRepository): CreatePage = CreatePage(repo = repo)
fun provideGetDefaultPageType(repo: UserSettingsRepository): GetDefaultEditorType =
GetDefaultEditorType(repo)
@JvmStatic
@Provides
@PerScreen
fun provideGetTemplates(repo: BlockRepository): GetTemplates = GetTemplates(
repo = repo,
dispatchers = AppCoroutineDispatchers(
io = Dispatchers.IO,
computation = Dispatchers.Default,
main = Dispatchers.Main
)
)
@JvmStatic
@Provides
@PerScreen
fun provideViewModelFactory(
createPage: CreatePage
): CreateObjectViewModel.Factory = CreateObjectViewModel.Factory(createPage)
createObject: CreateObject
): CreateObjectViewModel.Factory = CreateObjectViewModel.Factory(createObject = createObject)
}

View file

@ -24,8 +24,7 @@ import com.anytypeio.anytype.domain.objects.DeleteObjects
import com.anytypeio.anytype.domain.objects.ObjectStore
import com.anytypeio.anytype.domain.objects.SetObjectListIsArchived
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreatePage
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.CancelSearchSubscription
import com.anytypeio.anytype.domain.search.ObjectSearchSubscriptionContainer
import com.anytypeio.anytype.domain.search.SearchObjects
@ -79,7 +78,7 @@ object HomeDashboardModule {
cancelSearchSubscription: CancelSearchSubscription,
objectStore: ObjectStore,
featureToggles: FeatureToggles,
createNewObject: CreateNewObject,
createObject: CreateObject,
storeOfObjectTypes: StoreOfObjectTypes
): HomeDashboardViewModelFactory = HomeDashboardViewModelFactory(
getProfile = getProfile,
@ -98,24 +97,11 @@ object HomeDashboardModule {
objectSearchSubscriptionContainer = objectSearchSubscriptionContainer,
cancelSearchSubscription = cancelSearchSubscription,
objectStore = objectStore,
createNewObject = createNewObject,
createObject = createObject,
featureToggles = featureToggles,
storeOfObjectTypes = storeOfObjectTypes
)
@JvmStatic
@Provides
@PerScreen
fun provideCreateNewObject(
getDefaultEditorType: GetDefaultEditorType,
getTemplates: GetTemplates,
createPage: CreatePage,
) : CreateNewObject = CreateNewObject(
getDefaultEditorType,
getTemplates,
createPage
)
@JvmStatic
@Provides
@PerScreen
@ -153,15 +139,6 @@ object HomeDashboardModule {
provider = provider
)
@JvmStatic
@Provides
@PerScreen
fun provideCreatePageUseCase(
repo: BlockRepository
): CreatePage = CreatePage(
repo = repo
)
@JvmStatic
@Provides
@PerScreen
@ -287,4 +264,17 @@ object HomeDashboardModule {
main = Dispatchers.Main
)
)
@JvmStatic
@Provides
@PerScreen
fun getCreateObject(
repo: BlockRepository,
getTemplates: GetTemplates,
getDefaultEditorType: GetDefaultEditorType
): CreateObject = CreateObject(
repo = repo,
getTemplates = getTemplates,
getDefaultEditorType = getDefaultEditorType
)
}

View file

@ -54,7 +54,6 @@ import com.anytypeio.anytype.domain.download.DownloadFile
import com.anytypeio.anytype.domain.download.Downloader
import com.anytypeio.anytype.domain.event.interactor.EventChannel
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
import com.anytypeio.anytype.domain.icon.DocumentEmojiIconProvider
import com.anytypeio.anytype.domain.icon.SetDocumentImageIcon
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.misc.UrlBuilder
@ -63,11 +62,9 @@ import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.domain.objects.options.GetOptions
import com.anytypeio.anytype.domain.page.CloseBlock
import com.anytypeio.anytype.domain.page.CreateDocument
import com.anytypeio.anytype.domain.page.CreateNewDocument
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreateObjectAsMentionOrLink
import com.anytypeio.anytype.domain.page.CreateBlockLinkWithObject
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.page.CreatePage
import com.anytypeio.anytype.domain.page.OpenPage
import com.anytypeio.anytype.domain.page.Redo
import com.anytypeio.anytype.domain.page.Undo
@ -216,10 +213,9 @@ object EditorSessionModule {
interceptThreadStatus: InterceptThreadStatus,
updateLinkMarks: UpdateLinkMarks,
removeLinkMark: RemoveLinkMark,
createDocument: CreateDocument,
createObjectSet: CreateObjectSet,
createObject: CreateObject,
createNewDocument: CreateNewDocument,
createBlockLinkWithObject: CreateBlockLinkWithObject,
createObjectAsMentionOrLink: CreateObjectAsMentionOrLink,
documentExternalEventReducer: DocumentExternalEventReducer,
urlBuilder: UrlBuilder,
renderer: DefaultBlockViewRenderer,
@ -237,7 +233,7 @@ object EditorSessionModule {
setDocCoverImage: SetDocCoverImage,
setDocImageIcon: SetDocumentImageIcon,
editorTemplateDelegate: EditorTemplateDelegate,
createNewObject: CreateNewObject,
createObject: CreateObject,
storeOfRelations: StoreOfRelations,
storeOfObjectTypes: StoreOfObjectTypes,
objectToSet: ConvertObjectToSet,
@ -246,9 +242,8 @@ object EditorSessionModule {
): EditorViewModelFactory = EditorViewModelFactory(
openPage = openPage,
closeObject = closePage,
createDocument = createDocument,
createObject = createObject,
createNewDocument = createNewDocument,
createBlockLinkWithObject = createBlockLinkWithObject,
createObjectAsMentionOrLink = createObjectAsMentionOrLink,
interceptEvents = interceptEvents,
interceptThreadStatus = interceptThreadStatus,
updateLinkMarks = updateLinkMarks,
@ -271,7 +266,7 @@ object EditorSessionModule {
setDocCoverImage = setDocCoverImage,
setDocImageIcon = setDocImageIcon,
editorTemplateDelegate = editorTemplateDelegate,
createNewObject = createNewObject,
createObject = createObject,
storeOfRelations = storeOfRelations,
storeOfObjectTypes = storeOfObjectTypes,
objectToSet = objectToSet,
@ -279,19 +274,6 @@ object EditorSessionModule {
tableDelegate = tableDelegate
)
@JvmStatic
@Provides
@PerScreen
fun provideCreateNewObject(
getDefaultEditorType: GetDefaultEditorType,
getTemplates: GetTemplates,
createPage: CreatePage,
): CreateNewObject = CreateNewObject(
getDefaultEditorType,
getTemplates,
createPage
)
@JvmStatic
@Provides
@PerScreen
@ -645,15 +627,6 @@ object EditorUseCaseModule {
repo = repo
)
@JvmStatic
@Provides
@PerScreen
fun provideCreatePageUseCase(
repo: BlockRepository
): CreatePage = CreatePage(
repo = repo
)
@JvmStatic
@Provides
@PerScreen
@ -682,37 +655,26 @@ object EditorUseCaseModule {
repo = repo
)
@JvmStatic
@Provides
@PerScreen
fun provideCreateDocumentUseCase(
repo: BlockRepository,
documentEmojiIconProvider: DocumentEmojiIconProvider
): CreateDocument = CreateDocument(
repo = repo,
documentEmojiProvider = documentEmojiIconProvider
)
@JvmStatic
@Provides
@PerScreen
fun provideCreateObjectUseCase(
repo: BlockRepository,
documentEmojiIconProvider: DocumentEmojiIconProvider
): CreateObject = CreateObject(
repo = repo,
documentEmojiProvider = documentEmojiIconProvider
)
getTemplates: GetTemplates
): CreateBlockLinkWithObject =
CreateBlockLinkWithObject(repo = repo, getTemplates = getTemplates)
@JvmStatic
@Provides
@PerScreen
fun provideCreateNewDocumentUseCase(
fun provideCreateObjectAsMentionOrLink(
repo: BlockRepository,
documentEmojiIconProvider: DocumentEmojiIconProvider
): CreateNewDocument = CreateNewDocument(
getDefaultEditorType: GetDefaultEditorType,
getTemplates: GetTemplates
): CreateObjectAsMentionOrLink = CreateObjectAsMentionOrLink(
repo = repo,
documentEmojiProvider = documentEmojiIconProvider
getDefaultEditorType = getDefaultEditorType,
getTemplates = getTemplates
)
@JvmStatic
@ -1148,6 +1110,19 @@ object EditorUseCaseModule {
@PerScreen
fun getOptions(repo: BlockRepository) = GetOptions(repo)
@JvmStatic
@Provides
@PerScreen
fun getCreateObject(
repo: BlockRepository,
getTemplates: GetTemplates,
getDefaultEditorType: GetDefaultEditorType
): CreateObject = CreateObject(
repo = repo,
getTemplates = getTemplates,
getDefaultEditorType = getDefaultEditorType
)
@Module
interface Bindings {

View file

@ -36,8 +36,7 @@ import com.anytypeio.anytype.domain.objects.SetObjectIsArchived
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.domain.objects.options.GetOptions
import com.anytypeio.anytype.domain.page.CloseBlock
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreatePage
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.relations.AddFileToObject
import com.anytypeio.anytype.domain.relations.DeleteRelationFromDataView
import com.anytypeio.anytype.domain.search.CancelSearchSubscription
@ -142,7 +141,7 @@ object ObjectSetModule {
interceptEvents: InterceptEvents,
interceptThreadStatus: InterceptThreadStatus,
createDataViewObject: CreateDataViewObject,
createNewObject: CreateNewObject,
createObject: CreateObject,
reducer: ObjectSetReducer,
dispatcher: Dispatcher<Payload>,
delegator: Delegator<Action>,
@ -176,7 +175,7 @@ object ObjectSetModule {
analytics = analytics,
downloadUnsplashImage = downloadUnsplashImage,
setDocCoverImage = setDocCoverImage,
createNewObject = createNewObject,
createObject = createObject,
dataViewSubscriptionContainer = dataViewSubscriptionContainer,
cancelSearchSubscription = cancelSearchSubscription,
setDataViewSource = setDataViewSource,
@ -188,14 +187,14 @@ object ObjectSetModule {
@JvmStatic
@Provides
@PerScreen
fun provideCreateNewObject(
getDefaultEditorType: GetDefaultEditorType,
fun getCreateObject(
repo: BlockRepository,
getTemplates: GetTemplates,
createPage: CreatePage,
): CreateNewObject = CreateNewObject(
getDefaultEditorType,
getTemplates,
createPage
getDefaultEditorType: GetDefaultEditorType
): CreateObject = CreateObject(
repo = repo,
getTemplates = getTemplates,
getDefaultEditorType = getDefaultEditorType
)
@JvmStatic
@ -205,15 +204,6 @@ object ObjectSetModule {
repo: BlockRepository
): SetDataViewSource = SetDataViewSource(repo)
@JvmStatic
@Provides
@PerScreen
fun provideCreatePageUseCase(
repo: BlockRepository
): CreatePage = CreatePage(
repo = repo
)
@JvmStatic
@Provides
@PerScreen

View file

@ -7,6 +7,7 @@ import com.anytypeio.anytype.domain.auth.interactor.GetLastOpenedObject
import com.anytypeio.anytype.domain.auth.interactor.LaunchAccount
import com.anytypeio.anytype.domain.auth.interactor.LaunchWallet
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.config.FeaturesConfigProvider
@ -15,15 +16,17 @@ import com.anytypeio.anytype.domain.device.PathProvider
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.launch.SetDefaultEditorType
import com.anytypeio.anytype.domain.misc.AppActionManager
import com.anytypeio.anytype.domain.page.CreatePage
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.ObjectTypesSubscriptionManager
import com.anytypeio.anytype.domain.search.RelationsSubscriptionManager
import com.anytypeio.anytype.domain.templates.GetTemplates
import com.anytypeio.anytype.domain.workspace.WorkspaceManager
import com.anytypeio.anytype.presentation.splash.SplashViewModelFactory
import com.anytypeio.anytype.ui.splash.SplashFragment
import dagger.Module
import dagger.Provides
import dagger.Subcomponent
import kotlinx.coroutines.Dispatchers
@PerScreen
@Subcomponent(modules = [SplashModule::class])
@ -52,7 +55,7 @@ object SplashModule {
getLastOpenedObject: GetLastOpenedObject,
getDefaultEditorType: GetDefaultEditorType,
setDefaultEditorType: SetDefaultEditorType,
createPage: CreatePage,
createObject: CreateObject,
appActionManager: AppActionManager,
relationsSubscriptionManager: RelationsSubscriptionManager,
objectTypesSubscriptionManager: ObjectTypesSubscriptionManager
@ -64,7 +67,7 @@ object SplashModule {
getLastOpenedObject = getLastOpenedObject,
setDefaultEditorType = setDefaultEditorType,
getDefaultEditorType = getDefaultEditorType,
createPage = createPage,
createObject = createObject,
appActionManager = appActionManager,
relationsSubscriptionManager = relationsSubscriptionManager,
objectTypesSubscriptionManager = objectTypesSubscriptionManager
@ -132,7 +135,27 @@ object SplashModule {
SetDefaultEditorType(repo)
@JvmStatic
@PerScreen
@Provides
fun provideCreatePage(repo: BlockRepository): CreatePage = CreatePage(repo = repo)
@PerScreen
fun getCreateObject(
repo: BlockRepository,
getTemplates: GetTemplates,
getDefaultEditorType: GetDefaultEditorType
): CreateObject = CreateObject(
repo = repo,
getTemplates = getTemplates,
getDefaultEditorType = getDefaultEditorType
)
@JvmStatic
@Provides
@PerScreen
fun provideGetTemplates(repo: BlockRepository): GetTemplates = GetTemplates(
repo = repo,
dispatchers = AppCoroutineDispatchers(
io = Dispatchers.IO,
computation = Dispatchers.Default,
main = Dispatchers.Main
)
)
}

View file

@ -155,32 +155,33 @@ sealed class Command {
)
/**
* Command for creating a new document / page
* @property context id of the context of the block (i.e. page, dashboard or something else)
* @property target id of the block associated with the block we need to create
* @property position position of the block that we need to create in relation with the target block
* @property emoji random emoji for new page
* @property type object type
* @property layout object layout
* Command for creating a new object with linked block
* @property [context] id of the context of the block (i.e. page, dashboard or something else)
* @property [target] id of the block associated with the block we need to create
* @property [position] position of the block that we need to create in relation with the target block
* @property [template] id of the template for this object (optional)
* @property [prefilled] new object details
* @property [internalFlags] flags responsible for the object creation logic
*/
class CreateDocument(
data class CreateBlockLinkWithObject(
val context: Id,
val target: Id,
val position: Position,
val emoji: String?,
val type: String?,
val layout: ObjectType.Layout?,
val template: Id? = null
val template: Id?,
val prefilled: Struct,
val internalFlags: List<InternalFlags>
)
/**
* Command for creating a new document / page
* Command for creating a new object
* @property [prefilled] new object details
* @property [template] id of the template for this object (optional)
* @property [internalFlags] flags responsible for the object creation logic
*/
class CreateNewDocument(
val name: String,
val emoji: String?,
val type: String?
data class CreateObject(
val prefilled: Struct,
val template: Id?,
val internalFlags: List<InternalFlags>
)
class Move(

View file

@ -0,0 +1,8 @@
package com.anytypeio.anytype.core_models
data class CreateBlockLinkWithObjectResult(
val blockId: Id,
val objectId: Id,
val event: Payload
)

View file

@ -0,0 +1,7 @@
package com.anytypeio.anytype.core_models
data class CreateObjectResult(
val id: Id,
val event: Payload,
val details: Struct?
)

View file

@ -0,0 +1,19 @@
package com.anytypeio.anytype.core_models
sealed class InternalFlags {
/**
* show the object type selection interface
*/
object ShouldSelectType : InternalFlags()
/**
* Flag to remove the object from the account, in case of closing this object when it is empty
*/
object ShouldEmptyDelete : InternalFlags()
/**
* show the template selection interface
*/
object ShouldSelectTemplate : InternalFlags()
}

View file

@ -2,6 +2,8 @@ package com.anytypeio.anytype.data.auth.repo.block
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.CreateBlockLinkWithObjectResult
import com.anytypeio.anytype.core_models.CreateObjectResult
import com.anytypeio.anytype.core_models.DVFilter
import com.anytypeio.anytype.core_models.DVSort
import com.anytypeio.anytype.core_models.DVViewer
@ -9,6 +11,7 @@ import com.anytypeio.anytype.core_models.DVViewerType
import com.anytypeio.anytype.core_models.DocumentInfo
import com.anytypeio.anytype.core_models.Hash
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.InternalFlags
import com.anytypeio.anytype.core_models.Key
import com.anytypeio.anytype.core_models.ObjectInfoWithLinks
import com.anytypeio.anytype.core_models.ObjectType
@ -74,19 +77,15 @@ class BlockDataRepository(
command: Command.UpdateAlignment
): Payload = remote.updateAlignment(command)
override suspend fun createPage(
ctx: Id?,
emoji: String?,
isDraft: Boolean?,
type: String?,
template: Id?
) = remote.createPage(
ctx = ctx,
emoji = emoji,
isDraft = isDraft,
type = type,
template = template
)
override suspend fun createObject(
command: Command.CreateObject
): CreateObjectResult {
return remote.createObject(command)
}
override suspend fun createBlockLinkWithObject(
command: Command.CreateBlockLinkWithObject
): CreateBlockLinkWithObjectResult = remote.createBlockLinkWithObject(command)
override suspend fun closePage(id: String) {
remote.closePage(id)
@ -141,22 +140,6 @@ class BlockDataRepository(
Pair(ids, payload)
}
override suspend fun createDocument(
command: Command.CreateDocument
): Triple<String, String, Payload> {
return remote.createDocument(
command
).let { (id, target, payload) ->
Triple(id, target, payload)
}
}
override suspend fun createNewDocument(
command: Command.CreateNewDocument
): Id {
return remote.createNewDocument(command)
}
override suspend fun move(command: Command.Move): Payload {
return remote.move(command)
}
@ -382,16 +365,6 @@ class BlockDataRepository(
viewer = viewer
)
override suspend fun createDataViewObject(
type: Id,
template: Id?,
prefilled: Struct,
): Id = remote.createDataViewRecord(
template = template,
prefilled = prefilled,
type = type
)
override suspend fun searchObjects(
sorts: List<DVSort>,
filters: List<DVFilter>,
@ -460,8 +433,8 @@ class BlockDataRepository(
override suspend fun debugSync(): String = remote.debugSync()
override suspend fun debugTree(objectId: Id, path: String): String
= remote.debugTree(objectId = objectId, path = path)
override suspend fun debugTree(objectId: Id, path: String): String =
remote.debugTree(objectId = objectId, path = path)
override suspend fun debugLocalStore(path: String): String =
remote.debugLocalStore(path)
@ -551,7 +524,7 @@ class BlockDataRepository(
return remote.objectToSet(ctx, source)
}
override suspend fun clearBlockContent(ctx: Id, blockIds: List<Id>) : Payload {
override suspend fun clearBlockContent(ctx: Id, blockIds: List<Id>): Payload {
return remote.clearBlockContent(ctx, blockIds)
}

View file

@ -2,6 +2,8 @@ package com.anytypeio.anytype.data.auth.repo.block
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.CreateBlockLinkWithObjectResult
import com.anytypeio.anytype.core_models.CreateObjectResult
import com.anytypeio.anytype.core_models.DVFilter
import com.anytypeio.anytype.core_models.DVSort
import com.anytypeio.anytype.core_models.DVViewer
@ -35,8 +37,6 @@ interface BlockDataStore {
suspend fun updateAlignment(command: Command.UpdateAlignment): Payload
suspend fun openDashboard(contextId: String, id: String): Payload
suspend fun createDocument(command: Command.CreateDocument): Triple<Id, Id, Payload>
suspend fun createNewDocument(command: Command.CreateNewDocument): String
suspend fun updateDocumentTitle(command: Command.UpdateTitle)
suspend fun updateText(command: Command.UpdateText)
suspend fun updateTextStyle(command: Command.UpdateStyle): Payload
@ -48,13 +48,6 @@ interface BlockDataStore {
suspend fun uploadBlock(command: Command.UploadBlock): Payload
suspend fun move(command: Command.Move): Payload
suspend fun unlink(command: Command.Unlink): Payload
suspend fun createPage(
ctx: Id?,
emoji: String?,
isDraft: Boolean?,
type: String?,
template: Id?
): Id
suspend fun openPage(id: String): Payload
suspend fun openObjectSet(id: String): Payload
@ -116,12 +109,6 @@ interface BlockDataStore {
viewer: DVViewer
): Payload
suspend fun createDataViewRecord(
type: Id,
template: Id?,
prefilled: Struct,
): Id
suspend fun addDataViewViewer(
ctx: String,
target: String,
@ -307,4 +294,10 @@ interface BlockDataStore {
): Payload
suspend fun addObjectToWorkspace(objects: List<Id>) : List<Id>
suspend fun createObject(command: Command.CreateObject): CreateObjectResult
suspend fun createBlockLinkWithObject(
command: Command.CreateBlockLinkWithObject
): CreateBlockLinkWithObjectResult
}

View file

@ -2,6 +2,8 @@ package com.anytypeio.anytype.data.auth.repo.block
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.CreateBlockLinkWithObjectResult
import com.anytypeio.anytype.core_models.CreateObjectResult
import com.anytypeio.anytype.core_models.DVFilter
import com.anytypeio.anytype.core_models.DVSort
import com.anytypeio.anytype.core_models.DVViewer
@ -32,27 +34,21 @@ interface BlockRemote {
suspend fun unlink(command: Command.Unlink): Payload
suspend fun updateTextColor(command: Command.UpdateTextColor): Payload
suspend fun updateBackgroundColor(command: Command.UpdateBackgroundColor): Payload
suspend fun updateAlignment(command: Command.UpdateAlignment) : Payload
suspend fun updateAlignment(command: Command.UpdateAlignment): Payload
suspend fun createDocument(command: Command.CreateDocument): Triple<String, String, Payload>
suspend fun updateDocumentTitle(command: Command.UpdateTitle)
suspend fun updateText(command: Command.UpdateText)
suspend fun updateTextStyle(command: Command.UpdateStyle) : Payload
suspend fun updateTextStyle(command: Command.UpdateStyle): Payload
suspend fun setTextIcon(command: Command.SetTextIcon): Payload
suspend fun setLinkAppearance(command: Command.SetLinkAppearance): Payload
suspend fun updateCheckbox(command: Command.UpdateCheckbox): Payload
suspend fun move(command: Command.Move): Payload
suspend fun createPage(
ctx: Id?,
emoji: String?,
isDraft: Boolean?,
type: String?,
template: Id?
): Id
suspend fun createBlockLinkWithObject(
command: Command.CreateBlockLinkWithObject
): CreateBlockLinkWithObjectResult
suspend fun createPage(command: Command.CreateNewDocument): String
suspend fun openPage(id: String): Payload
suspend fun openProfile(id: String): Payload
suspend fun openObjectSet(id: String): Payload
@ -68,15 +64,15 @@ interface BlockRemote {
suspend fun removeDocumentCover(ctx: String): Payload
suspend fun removeDocumentIcon(ctx: Id): Payload
suspend fun uploadBlock(command: Command.UploadBlock): Payload
suspend fun setupBookmark(command: Command.SetupBookmark) : Payload
suspend fun setupBookmark(command: Command.SetupBookmark): Payload
suspend fun createAndFetchBookmarkBlock(command: Command.CreateBookmark): Payload
suspend fun createBookmarkObject(url: Url) : Id
suspend fun createBookmarkObject(url: Url): Id
suspend fun fetchBookmarkObject(ctx: Id, url: Url)
suspend fun undo(command: Command.Undo) : Payload
suspend fun redo(command: Command.Redo) : Payload
suspend fun undo(command: Command.Undo): Payload
suspend fun redo(command: Command.Redo): Payload
suspend fun turnIntoDocument(command: Command.TurnIntoDocument): List<Id>
suspend fun paste(command: Command.Paste) : Response.Clipboard.Paste
suspend fun copy(command: Command.Copy) : Response.Clipboard.Copy
suspend fun paste(command: Command.Paste): Response.Clipboard.Paste
suspend fun copy(command: Command.Copy): Response.Clipboard.Copy
suspend fun uploadFile(command: Command.UploadFile): String
suspend fun downloadFile(command: Command.DownloadFile): String
@ -117,18 +113,13 @@ interface BlockRemote {
targets: List<String>,
style: Block.Content.Text.Style
): Payload
suspend fun duplicateDataViewViewer(
context: String,
target: String,
viewer: DVViewer
): Payload
suspend fun createDataViewObject(
type: Id,
template: Id?,
prefilled: Struct,
): Id
suspend fun addDataViewViewer(
ctx: String,
target: String,
@ -174,7 +165,7 @@ interface BlockRemote {
suspend fun cancelObjectSearchSubscription(subscriptions: List<Id>)
suspend fun relationListAvailable(ctx: Id): List<Relation>
suspend fun addRelationToObject(ctx: Id, relation: Key) : Payload
suspend fun addRelationToObject(ctx: Id, relation: Key): Payload
suspend fun deleteRelationFromObject(ctx: Id, relation: Key): Payload
suspend fun debugSync(): String
@ -198,13 +189,13 @@ interface BlockRemote {
suspend fun addToFeaturedRelations(ctx: Id, relations: List<Id>): Payload
suspend fun removeFromFeaturedRelations(ctx: Id, relations: List<Id>): Payload
suspend fun setObjectIsFavorite(ctx: Id, isFavorite: Boolean) : Payload
suspend fun setObjectIsArchived(ctx: Id, isArchived: Boolean) : Payload
suspend fun setObjectIsFavorite(ctx: Id, isFavorite: Boolean): Payload
suspend fun setObjectIsArchived(ctx: Id, isArchived: Boolean): Payload
suspend fun setObjectListIsArchived(targets: List<Id>, isArchived: Boolean)
suspend fun deleteObjects(targets: List<Id>)
suspend fun setObjectLayout(ctx: Id, layout: ObjectType.Layout) : Payload
suspend fun setObjectLayout(ctx: Id, layout: ObjectType.Layout): Payload
suspend fun clearFileCache()
@ -231,17 +222,17 @@ interface BlockRemote {
format: RelationFormat,
formatObjectTypes: List<Id>,
prefilled: Struct
) : ObjectWrapper.Relation
): ObjectWrapper.Relation
suspend fun createRelationOption(
relation: Id,
name: String,
color: String
) : ObjectWrapper.Option
): ObjectWrapper.Option
suspend fun clearBlockContent(ctx: Id, blockIds: List<Id>) : Payload
suspend fun clearBlockContent(ctx: Id, blockIds: List<Id>): Payload
suspend fun clearBlockStyle(ctx: Id, blockIds: List<Id>) : Payload
suspend fun clearBlockStyle(ctx: Id, blockIds: List<Id>): Payload
suspend fun fillTableColumn(ctx: Id, blockIds: List<Id>): Payload
@ -307,4 +298,6 @@ interface BlockRemote {
): Payload
suspend fun addObjectToWorkspace(objects: List<Id>): List<Id>
suspend fun createObject(command: Command.CreateObject): CreateObjectResult
}

View file

@ -2,12 +2,15 @@ package com.anytypeio.anytype.data.auth.repo.block
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.CreateBlockLinkWithObjectResult
import com.anytypeio.anytype.core_models.CreateObjectResult
import com.anytypeio.anytype.core_models.DVFilter
import com.anytypeio.anytype.core_models.DVSort
import com.anytypeio.anytype.core_models.DVViewer
import com.anytypeio.anytype.core_models.DVViewerType
import com.anytypeio.anytype.core_models.DocumentInfo
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.InternalFlags
import com.anytypeio.anytype.core_models.Key
import com.anytypeio.anytype.core_models.ObjectInfoWithLinks
import com.anytypeio.anytype.core_models.ObjectType
@ -32,19 +35,9 @@ class BlockRemoteDataStore(private val remote: BlockRemote) : BlockDataStore {
remote.closeDashboard(id = id)
}
override suspend fun createPage(
ctx: Id?,
emoji: String?,
isDraft: Boolean?,
type: String?,
template: Id?
): Id = remote.createPage(
ctx = ctx,
emoji = emoji,
isDraft = isDraft,
type = type,
template = template
)
override suspend fun createBlockLinkWithObject(
command: Command.CreateBlockLinkWithObject
): CreateBlockLinkWithObjectResult = remote.createBlockLinkWithObject(command)
override suspend fun openPage(id: String): Payload = remote.openPage(id)
override suspend fun openProfile(id: String): Payload = remote.openProfile(id)
@ -99,14 +92,6 @@ class BlockRemoteDataStore(private val remote: BlockRemote) : BlockDataStore {
command: Command.Create
): Pair<String, Payload> = remote.create(command)
override suspend fun createDocument(
command: Command.CreateDocument
): Triple<String, String, Payload> = remote.createDocument(command)
override suspend fun createNewDocument(
command: Command.CreateNewDocument
): String = remote.createPage(command)
override suspend fun move(command: Command.Move): Payload {
return remote.move(command)
}
@ -281,16 +266,6 @@ class BlockRemoteDataStore(private val remote: BlockRemote) : BlockDataStore {
viewer = viewer
)
override suspend fun createDataViewRecord(
type: Id,
template: Id?,
prefilled: Struct,
): Id = remote.createDataViewObject(
template = template,
prefilled = prefilled,
type = type
)
override suspend fun addDataViewViewer(
ctx: String,
target: String,
@ -648,4 +623,10 @@ class BlockRemoteDataStore(private val remote: BlockRemote) : BlockDataStore {
override suspend fun addObjectToWorkspace(objects: List<Id>): List<Id> {
return remote.addObjectToWorkspace(objects)
}
override suspend fun createObject(
command: Command.CreateObject
): CreateObjectResult {
return remote.createObject(command)
}
}

View file

@ -2,6 +2,8 @@ package com.anytypeio.anytype.domain.block.repo
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.CreateBlockLinkWithObjectResult
import com.anytypeio.anytype.core_models.CreateObjectResult
import com.anytypeio.anytype.core_models.DVFilter
import com.anytypeio.anytype.core_models.DVSort
import com.anytypeio.anytype.core_models.DVViewer
@ -9,6 +11,7 @@ import com.anytypeio.anytype.core_models.DVViewerType
import com.anytypeio.anytype.core_models.DocumentInfo
import com.anytypeio.anytype.core_models.Hash
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.InternalFlags
import com.anytypeio.anytype.core_models.Key
import com.anytypeio.anytype.core_models.ObjectInfoWithLinks
import com.anytypeio.anytype.core_models.ObjectType
@ -50,16 +53,13 @@ interface BlockRepository {
suspend fun create(command: Command.Create): Pair<Id, Payload>
/**
* Creates a new document / page.
* @return pair of values, where the first one is block id and the second one is target id.
* Creates just the new page, without adding the link to it from some other page
*/
suspend fun createDocument(command: Command.CreateDocument): Triple<Id, Id, Payload>
suspend fun createObject(command: Command.CreateObject): CreateObjectResult
/**
* Creates a new document / page, without positioning and targets.
* @return block id of the new document.
*/
suspend fun createNewDocument(command: Command.CreateNewDocument): Id
suspend fun createBlockLinkWithObject(
command: Command.CreateBlockLinkWithObject
): CreateBlockLinkWithObjectResult
suspend fun merge(command: Command.Merge): Payload
@ -90,14 +90,6 @@ interface BlockRepository {
suspend fun setRelationKey(command: Command.SetRelationKey): Payload
suspend fun createPage(
ctx: Id?,
emoji: String?,
isDraft: Boolean?,
type: Id?,
template: Id?
): Id
suspend fun openObjectPreview(id: Id): Result<Payload>
suspend fun openPage(id: String): Result<Payload>
@ -174,12 +166,6 @@ interface BlockRepository {
viewer: DVViewer
): Payload
suspend fun createDataViewObject(
type: Id,
template: Id?,
prefilled: Struct,
): Id
suspend fun addDataViewViewer(
ctx: String,
target: String,

View file

@ -1,5 +1,6 @@
package com.anytypeio.anytype.domain.dataview.interactor
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.DVFilter
import com.anytypeio.anytype.core_models.DVFilterCondition
import com.anytypeio.anytype.core_models.Id
@ -7,6 +8,7 @@ import com.anytypeio.anytype.core_models.Key
import com.anytypeio.anytype.core_models.ObjectTypeIds
import com.anytypeio.anytype.core_models.Relation
import com.anytypeio.anytype.core_models.RelationFormat
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.Struct
import com.anytypeio.anytype.domain.base.BaseUseCase
import com.anytypeio.anytype.domain.block.repo.BlockRepository
@ -25,40 +27,51 @@ class CreateDataViewObject(
) : BaseUseCase<Id, CreateDataViewObject.Params>() {
override suspend fun run(params: Params) = safe {
when(params) {
when (params) {
is Params.SetByType -> {
repo.createDataViewObject(
val command = Command.CreateObject(
template = resolveTemplateForNewObject(type = params.type),
prefilled = resolveSetByTypePrefilledObjectData(
filters = params.filters
filters = params.filters,
type = params.type
),
type = params.type
internalFlags = listOf()
)
val result = repo.createObject(command)
result.id
}
is Params.SetByRelation -> {
val type = resolveDefaultObjectType()
repo.createDataViewObject(
val command = Command.CreateObject(
template = resolveTemplateForNewObject(type = type),
prefilled = resolveSetByRelationPrefilledObjectData(
filters = params.filters,
relations = params.relations
relations = params.relations,
type = type
),
type = type
internalFlags = listOf()
)
val result = repo.createObject(command)
result.id
}
}
}
private suspend fun resolveSetByTypePrefilledObjectData(filters: List<DVFilter>): Struct = buildMap {
filters.forEach { filter ->
val relation = storeOfRelations.getByKey(filter.relationKey)
if (relation != null && relation.isReadOnly == false) {
if (filter.condition == DVFilterCondition.ALL_IN || filter.condition == DVFilterCondition.IN || filter.condition == DVFilterCondition.EQUAL) {
filter.value?.let { put(filter.relationKey, it) }
private suspend fun resolveSetByTypePrefilledObjectData(
filters: List<DVFilter>,
type: Id
): Struct =
buildMap {
filters.forEach { filter ->
val relation = storeOfRelations.getByKey(filter.relationKey)
if (relation != null && relation.isReadOnly == false) {
if (filter.condition == DVFilterCondition.ALL_IN || filter.condition == DVFilterCondition.IN || filter.condition == DVFilterCondition.EQUAL) {
filter.value?.let { put(filter.relationKey, it) }
}
}
}
put(Relations.TYPE, type)
}
}
private suspend fun resolveTemplateForNewObject(type: Id): Id? {
val templates = try {
@ -71,7 +84,8 @@ class CreateDataViewObject(
private suspend fun resolveSetByRelationPrefilledObjectData(
filters: List<DVFilter>,
relations: List<Key>
relations: List<Key>,
type: Id? = null
): Struct = try {
buildMap {
filters.forEach { filter ->
@ -93,12 +107,15 @@ class CreateDataViewObject(
put(relation.key, resolveDefaultValueByFormat(relation.relationFormat))
}
}
if (type != null) {
put(Relations.TYPE, type)
}
}
} catch (e: Exception) {
emptyMap()
}
private suspend fun resolveDefaultObjectType() : Id {
private suspend fun resolveDefaultObjectType(): Id {
return try {
getDefaultEditorType.run(Unit).type ?: ObjectTypeIds.NOTE
} catch (e: Exception) {
@ -106,8 +123,8 @@ class CreateDataViewObject(
}
}
private fun resolveDefaultValueByFormat(format: RelationFormat) : Any? {
when(format) {
private fun resolveDefaultValueByFormat(format: RelationFormat): Any? {
when (format) {
Relation.Format.LONG_TEXT,
Relation.Format.SHORT_TEXT,
Relation.Format.URL,
@ -133,6 +150,7 @@ class CreateDataViewObject(
val type: Id,
val filters: List<DVFilter>
) : Params()
data class SetByRelation(
val filters: List<DVFilter>,
val relations: List<Id>

View file

@ -0,0 +1,68 @@
package com.anytypeio.anytype.domain.page
import com.anytypeio.anytype.core_models.*
import com.anytypeio.anytype.domain.base.ResultInteractor
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.templates.GetTemplates
/**
* UseCase for creating a new Object with block linked to this Object
*/
class CreateBlockLinkWithObject(
private val repo: BlockRepository,
private val getTemplates: GetTemplates
) : ResultInteractor<CreateBlockLinkWithObject.Params, CreateBlockLinkWithObject.Result>() {
override suspend fun doWork(params: Params): Result {
val prefilled = buildMap {
put(Relations.TYPE, params.type)
}
val template = getTemplates.run(GetTemplates.Params(params.type)).singleOrNull()?.id
val command = Command.CreateBlockLinkWithObject(
context = params.context,
target = params.target,
position = params.position,
prefilled = prefilled,
template = template,
internalFlags = listOf()
)
val result = repo.createBlockLinkWithObject(command)
return Result(
id = result.blockId,
objectId = result.objectId,
payload = result.event
)
}
/**
* Params for creating a new object
* @property context id of the context of the block (i.e. page, dashboard or something else)
* @property target id of the block associated with the block we need to create
* @property position position of the block that we need to create in relation with the target block
* @property type assumed type of new object
*/
data class Params(
val context: Id,
val target: Id,
val position: Position,
val type: String
)
/**
* Result for this use-case
* @property id id of the new block (link)
* @property objectId id of the new Object linked to this new block[id]
* @property payload payload of events
*/
data class Result(
val id: Id,
val objectId: Id,
val payload: Payload
)
}

View file

@ -1,64 +0,0 @@
package com.anytypeio.anytype.domain.page
import com.anytypeio.anytype.core_models.*
import com.anytypeio.anytype.domain.base.BaseUseCase
import com.anytypeio.anytype.domain.base.Either
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.icon.DocumentEmojiIconProvider
/**
* Use-case for creating a new document.
* Should return a pair of ids, where the first one is block id, the second one is target id.
*/
class CreateDocument(
private val repo: BlockRepository,
private val documentEmojiProvider: DocumentEmojiIconProvider
) : BaseUseCase<CreateDocument.Result, CreateDocument.Params>() {
override suspend fun run(params: Params) = try {
repo.createDocument(
command = Command.CreateDocument(
context = params.context,
target = params.target,
position = params.position,
emoji = null,
type = null,
layout = null
)
).let { (id, target, payload) ->
Either.Right(
Result(
id = id,
target = target,
payload = payload
)
)
}
} catch (t: Throwable) {
Either.Left(t)
}
/**
* Params for creating a new document
* @property context id of the context of the block (i.e. page, dashboard or something else)
* @property target id of the block associated with the block we need to create
* @property position position of the block that we need to create in relation with the target block
*/
data class Params(
val context: Id,
val target: Id,
val position: Position
)
/**
* Result for this use-case
* @property id id of the new block (link)
* @property target id of the target for this new block
* @property payload payload of events
*/
data class Result(
val id: String,
val target: String,
val payload: Payload
)
}

View file

@ -1,44 +0,0 @@
package com.anytypeio.anytype.domain.page
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.domain.base.BaseUseCase
import com.anytypeio.anytype.domain.base.Either
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.icon.DocumentEmojiIconProvider
class CreateNewDocument(
private val repo: BlockRepository,
private val documentEmojiProvider: DocumentEmojiIconProvider
) : BaseUseCase<CreateNewDocument.Result, CreateNewDocument.Params>() {
override suspend fun run(params: Params): Either<Throwable, Result> = safe {
val emoji = null
val id = repo.createNewDocument(
command = Command.CreateNewDocument(
name = params.name,
emoji = emoji,
type = params.type
)
)
Result(
id = id,
name = params.name,
emoji = emoji
)
}
/**
* [name] name for new object
* [type] type for new object
*/
data class Params(
val name: String,
val type: String?
)
data class Result(
val id: String,
val name: String,
val emoji: String?
)
}

View file

@ -1,45 +0,0 @@
package com.anytypeio.anytype.domain.page
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.domain.base.ResultInteractor
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.templates.GetTemplates
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
class CreateNewObject(
private val getDefaultEditorType: GetDefaultEditorType,
private val getTemplates: GetTemplates,
private val createPage: CreatePage,
) : ResultInteractor<Unit, Id>() {
private suspend fun createPageWithType(type: Id): Id {
val template = getTemplates.run(GetTemplates.Params(type)).singleOrNull()?.id
return createPage.run(
CreatePage.Params(
ctx = null,
isDraft = template == null,
type = type,
emoji = null,
template = template
)
)
}
override suspend fun doWork(params: Unit) = getDefaultEditorType.asFlow(Unit)
.map { it.type }
.catch { emit(null) }
.map { type ->
if (type == null) {
createPage.run(
CreatePage.Params(
isDraft = true
)
)
} else {
createPageWithType(type)
}
}
.first()
}

View file

@ -1,65 +1,64 @@
package com.anytypeio.anytype.domain.page
import com.anytypeio.anytype.core_models.*
import com.anytypeio.anytype.domain.base.BaseUseCase
import com.anytypeio.anytype.domain.base.Either
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.InternalFlags
import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.domain.base.ResultInteractor
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.icon.DocumentEmojiIconProvider
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.templates.GetTemplates
/**
* Use case for creating a new object
*/
class CreateObject(
private val repo: BlockRepository,
private val documentEmojiProvider: DocumentEmojiIconProvider
) : BaseUseCase<CreateObject.Result, CreateObject.Params>() {
private val getDefaultEditorType: GetDefaultEditorType,
private val getTemplates: GetTemplates
) : ResultInteractor<CreateObject.Param, CreateObject.Result>() {
override suspend fun run(params: Params) = try {
repo.createDocument(
command = Command.CreateDocument(
context = params.context,
target = params.target,
position = params.position,
emoji = null,
type = params.type,
layout = params.layout,
template = params.template
)
).let { (id, target, payload) ->
Either.Right(
Result(
id = id,
target = target,
payload = payload
)
)
override suspend fun doWork(params: Param): Result {
val type = params.type ?: getDefaultEditorType.run(Unit).type
val template = if (type != null) {
getTemplates.run(GetTemplates.Params(type = type)).singleOrNull()?.id
} else {
null
}
} catch (t: Throwable) {
Either.Left(t)
val internalFlags = if (template != null) {
listOf()
} else {
listOf(InternalFlags.ShouldSelectType, InternalFlags.ShouldEmptyDelete)
}
val prefilled = buildMap {
if (type != null) put(Relations.TYPE, type)
}
val command = Command.CreateObject(
template = template,
prefilled = prefilled,
internalFlags = internalFlags
)
val result = repo.createObject(command)
return Result(
objectId = result.id,
event = result.event
)
}
/**
* Params for creating a new object
* @property context id of the context of the block (i.e. page, dashboard or something else)
* @property target id of the block associated with the block we need to create
* @property position position of the block that we need to create in relation with the target block
* @property [template] id of the template for this object (optional)
*/
data class Params(
val context: Id,
val target: Id,
val position: Position,
val type: String,
val layout: ObjectType.Layout?,
val template: Id? = null
data class Param(
val type: String?
)
/**
* Result for this use-case
* @property id id of the new block (link)
* @property target id of the target for this new block
* @property payload payload of events
*/
data class Result(
val id: Id,
val target: Id,
val payload: Payload
val objectId: Id,
val event: Payload
)
}

View file

@ -0,0 +1,61 @@
package com.anytypeio.anytype.domain.page
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.domain.base.ResultInteractor
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.templates.GetTemplates
/**
* UseCase for creating a new object as mention or as text link markup
*/
class CreateObjectAsMentionOrLink(
private val repo: BlockRepository,
private val getDefaultEditorType: GetDefaultEditorType,
private val getTemplates: GetTemplates
) : ResultInteractor<CreateObjectAsMentionOrLink.Params, CreateObjectAsMentionOrLink.Result>() {
override suspend fun doWork(params: Params): Result {
val type = params.type ?: getDefaultEditorType.run(Unit).type
val prefilled = buildMap {
if (type != null) put(Relations.TYPE, type)
put(Relations.NAME, params.name)
}
val template = if (type != null) {
getTemplates.run(GetTemplates.Params(type)).singleOrNull()?.id
} else {
null
}
val command = Command.CreateObject(
template = template,
prefilled = prefilled,
internalFlags = listOf()
)
val result = repo.createObject(command)
return Result(
id = result.id,
name = params.name
)
}
/**
* [name] name for new object
* [type] type for new object
*/
data class Params(
val name: String,
val type: String?
)
data class Result(
val id: String,
val name: String
)
}

View file

@ -1,45 +0,0 @@
package com.anytypeio.anytype.domain.page
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.domain.base.ResultInteractor
import com.anytypeio.anytype.domain.block.repo.BlockRepository
/**
* A use-case for creating a new page.
* Currently used for creating a new page inside a dashboard.
*/
class CreatePage(
private val repo: BlockRepository
) : ResultInteractor<CreatePage.Params, Id>() {
override suspend fun doWork(params: Params): Id = repo.createPage(
ctx = params.ctx,
emoji = null,
isDraft = params.isDraft,
type = params.type,
template = params.template
)
/**
* @property [ctx] context (parent) for this new page.
* @property [type] type of created object
* @property [isDraft] should this object be in Draft state
* @property [template] id of the template for this object (optional)
*/
data class Params(
val ctx: Id?,
val type: String?,
val emoji: String?,
val isDraft: Boolean?,
val template: Id? = null
) {
constructor(
isDraft: Boolean?,
) : this(
ctx = null,
type = null,
emoji = null,
isDraft = isDraft,
template = null)
}
}

View file

@ -0,0 +1,180 @@
package com.anytypeio.anytype.domain.page
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.CoroutineTestRule
import com.anytypeio.anytype.core_models.CreateBlockLinkWithObjectResult
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.core_models.Position
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.templates.GetTemplates
import com.anytypeio.anytype.test_utils.MockDataFactory
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.stub
import com.nhaarman.mockitokotlin2.times
import com.nhaarman.mockitokotlin2.verifyBlocking
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.Mock
import org.mockito.junit.MockitoJUnit
class CreateBlockLinkWithObjectTest {
@get:Rule
val mockitoRule = MockitoJUnit.rule()
@ExperimentalCoroutinesApi
@get:Rule
var rule = CoroutineTestRule()
@Mock
lateinit var repo: BlockRepository
@Mock
lateinit var getTemplates: GetTemplates
lateinit var createBlockLinkWithObject: CreateBlockLinkWithObject
@Before
fun setup() {
createBlockLinkWithObject = CreateBlockLinkWithObject(repo, getTemplates)
}
@Test
fun `when type without template - should send proper params`() = runBlocking {
//SETUP
val context = MockDataFactory.randomString()
val target = MockDataFactory.randomString()
val position = Position.LEFT
val type = MockDataFactory.randomString()
val name = MockDataFactory.randomString()
stubCreateBlockLinkWithObject()
givenGetTemplates(listOf())
//TESTING
val params = CreateBlockLinkWithObject.Params(
context = context,
target = target,
position = position,
type = type
)
createBlockLinkWithObject.run(params)
//ASSERT
val commands = Command.CreateBlockLinkWithObject(
context = context,
target = target,
position = position,
prefilled = buildMap {
put(Relations.TYPE, type)
},
template = null,
internalFlags = listOf()
)
verifyBlocking(repo, times(1)) { createBlockLinkWithObject(commands) }
}
@Test
fun `when type with one template - should send proper params`() = runBlocking {
//SETUP
val context = MockDataFactory.randomString()
val target = MockDataFactory.randomString()
val position = Position.LEFT
val type = MockDataFactory.randomString()
val template = MockDataFactory.randomString()
stubCreateBlockLinkWithObject()
givenGetTemplates(listOf(ObjectWrapper.Basic(buildMap {
put(Relations.ID, template)
})))
//TESTING
val params = CreateBlockLinkWithObject.Params(
context = context,
target = target,
position = position,
type = type
)
createBlockLinkWithObject.run(params)
//ASSERT
val commands = Command.CreateBlockLinkWithObject(
context = context,
target = target,
position = position,
prefilled = buildMap {
put(Relations.TYPE, type)
},
template = template,
internalFlags = listOf()
)
verifyBlocking(repo, times(1)) { createBlockLinkWithObject(commands) }
}
@Test
fun `when type with two templates - should send proper params`() = runBlocking {
//SETUP
val context = MockDataFactory.randomString()
val target = MockDataFactory.randomString()
val position = Position.LEFT
val type = MockDataFactory.randomString()
val templateOne = MockDataFactory.randomString()
val templateTwo = MockDataFactory.randomString()
stubCreateBlockLinkWithObject()
givenGetTemplates(
listOf(
ObjectWrapper.Basic(buildMap {
put(Relations.ID, templateOne)
}),
ObjectWrapper.Basic(buildMap {
put(Relations.ID, templateTwo)
})
)
)
//TESTING
val params = CreateBlockLinkWithObject.Params(
context = context,
target = target,
position = position,
type = type
)
createBlockLinkWithObject.run(params)
//ASSERT
val commands = Command.CreateBlockLinkWithObject(
context = context,
target = target,
position = position,
prefilled = buildMap {
put(Relations.TYPE, type)
},
template = null,
internalFlags = listOf()
)
verifyBlocking(repo, times(1)) { createBlockLinkWithObject(commands) }
}
private fun givenGetTemplates(objects: List<ObjectWrapper.Basic> = listOf()) {
getTemplates.stub {
onBlocking { run(any()) } doReturn objects
}
}
private fun stubCreateBlockLinkWithObject() {
repo.stub {
onBlocking { createBlockLinkWithObject(any()) } doReturn CreateBlockLinkWithObjectResult(
blockId = "",
objectId = "",
event = Payload(context = "", events = listOf())
)
}
}
}

View file

@ -1,120 +0,0 @@
package com.anytypeio.anytype.domain.page
import com.anytypeio.anytype.core_models.CoroutineTestRule
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.templates.GetTemplates
import com.anytypeio.anytype.test_utils.MockDataFactory
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.stub
import com.nhaarman.mockitokotlin2.times
import com.nhaarman.mockitokotlin2.verifyBlocking
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.runBlocking
import org.junit.Rule
import org.junit.Test
import org.mockito.Mock
import org.mockito.junit.MockitoJUnit
class CreateNewObjectTest {
@get:Rule
val mockitoRule = MockitoJUnit.rule()
@get:Rule
var rule = CoroutineTestRule()
@Mock
lateinit var createPage: CreatePage
@Mock
lateinit var getDefaultEditorType: GetDefaultEditorType
@Mock
lateinit var getTemplates: GetTemplates
@Test
fun `should start creating page`() {
givenCreatePage()
givenGetDefaultObjectType()
runBlocking { givenCreateNewObject().run(any()) }
verifyBlocking(createPage, times(1)) { run(any()) }
}
@Test
fun `should create new object with null template and isDraft true params`() {
val type = MockDataFactory.randomString()
givenCreatePage()
givenGetTemplates()
givenGetDefaultObjectType(type = type)
runBlocking { givenCreateNewObject().run(Unit) }
val params = CreatePage.Params(
ctx = null,
type = type,
emoji = null,
isDraft = true,
template = null
)
verifyBlocking(createPage, times(1)) { run(params) }
}
@Test
fun `should create new object with non nullable template and isDraft false params`() {
val templateId = MockDataFactory.randomUuid()
val type = MockDataFactory.randomString()
val obj = ObjectWrapper.Basic(mapOf("id" to templateId))
givenCreatePage()
givenGetTemplates(objects = listOf(obj))
givenGetDefaultObjectType(type = type)
runBlocking { givenCreateNewObject().run(Unit) }
val params = CreatePage.Params(
ctx = null,
type = type,
emoji = null,
isDraft = false,
template = templateId
)
verifyBlocking(createPage, times(1)) { run(params) }
}
private fun givenCreatePage(id: String = "") {
createPage.stub {
onBlocking { run(any()) } doReturn id
}
}
private fun givenGetDefaultObjectType(type: String? = null, name: String? = null) {
getDefaultEditorType.stub {
onBlocking { asFlow(Unit) } doReturn flow {
emit(
GetDefaultEditorType.Response(
type,
name
)
)
}
}
}
private fun givenGetTemplates(objects: List<ObjectWrapper.Basic> = listOf()) {
getTemplates.stub {
onBlocking { run(any()) } doReturn objects
}
}
private fun givenCreateNewObject() = CreateNewObject(
getDefaultEditorType, getTemplates, createPage
)
}

View file

@ -0,0 +1,212 @@
package com.anytypeio.anytype.domain.page
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.CoroutineTestRule
import com.anytypeio.anytype.core_models.CreateObjectResult
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.templates.GetTemplates
import com.anytypeio.anytype.test_utils.MockDataFactory
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.stub
import com.nhaarman.mockitokotlin2.times
import com.nhaarman.mockitokotlin2.verifyBlocking
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.Mock
import org.mockito.junit.MockitoJUnit
import org.mockito.kotlin.verifyNoInteractions
class CreateObjectAsMentionOrLinkTest {
@get:Rule
val mockitoRule = MockitoJUnit.rule()
@ExperimentalCoroutinesApi
@get:Rule
var rule = CoroutineTestRule()
@Mock
lateinit var repo: BlockRepository
@Mock
lateinit var getDefaultEditorType: GetDefaultEditorType
@Mock
lateinit var getTemplates: GetTemplates
lateinit var createObjectAsMentionOrLink: CreateObjectAsMentionOrLink
@Before
fun setup() {
createObjectAsMentionOrLink =
CreateObjectAsMentionOrLink(repo, getDefaultEditorType, getTemplates)
}
@Test
fun `when type is null and default type is null - should send proper params`() = runBlocking {
//SETUP
val type = null
val name = MockDataFactory.randomString()
givenGetDefaultObjectType()
stubCreateObject()
//TESTING
val params = CreateObjectAsMentionOrLink.Params(
name = name,
type = type
)
createObjectAsMentionOrLink.run(params)
//ASSERT
verifyNoInteractions(getTemplates)
val commands = Command.CreateObject(
prefilled = buildMap {
put(Relations.NAME, name)
},
template = null,
internalFlags = listOf()
)
verifyBlocking(repo, times(1)) { createObject(commands) }
}
@Test
fun `when type is null and default type is not null without template - should send proper params`() =
runBlocking {
//SETUP
val type = null
val name = MockDataFactory.randomString()
val typeDefault = MockDataFactory.randomString()
val typeDefaultName = MockDataFactory.randomString()
givenGetDefaultObjectType(type = typeDefault, name = typeDefaultName)
givenGetTemplates()
stubCreateObject()
//TESTING
val params = CreateObjectAsMentionOrLink.Params(
name = name,
type = type
)
createObjectAsMentionOrLink.run(params)
//ASSERT
val commands = Command.CreateObject(
prefilled = buildMap {
put(Relations.TYPE, typeDefault)
put(Relations.NAME, name)
},
template = null,
internalFlags = listOf()
)
verifyBlocking(repo, times(1)) { createObject(commands) }
}
@Test
fun `when type is null and default type is not null with one template - should send proper params`() =
runBlocking {
//SETUP
val type = null
val name = MockDataFactory.randomString()
val typeDefault = MockDataFactory.randomString()
val typeDefaultName = MockDataFactory.randomString()
val template = MockDataFactory.randomString()
givenGetDefaultObjectType(type = typeDefault, name = typeDefaultName)
givenGetTemplates(listOf(ObjectWrapper.Basic(buildMap {
put(Relations.ID, template)
})))
stubCreateObject()
//TESTING
val params = CreateObjectAsMentionOrLink.Params(
name = name,
type = type
)
createObjectAsMentionOrLink.run(params)
//ASSERT
val commands = Command.CreateObject(
prefilled = buildMap {
put(Relations.TYPE, typeDefault)
put(Relations.NAME, name)
},
template = template,
internalFlags = listOf()
)
verifyBlocking(repo, times(1)) { createObject(commands) }
}
@Test
fun `when type is null and default type is not null with two templates - should send proper params`() =
runBlocking {
//SETUP
val type = null
val name = MockDataFactory.randomString()
val typeDefault = MockDataFactory.randomString()
val typeDefaultName = MockDataFactory.randomString()
val templateOne = MockDataFactory.randomString()
val templateTwo = MockDataFactory.randomString()
givenGetTemplates(
listOf(
ObjectWrapper.Basic(buildMap {
put(Relations.ID, templateOne)
}),
ObjectWrapper.Basic(buildMap {
put(Relations.ID, templateTwo)
})
)
)
givenGetDefaultObjectType(type = typeDefault, name = typeDefaultName)
stubCreateObject()
//TESTING
val params = CreateObjectAsMentionOrLink.Params(
name = name,
type = type
)
createObjectAsMentionOrLink.run(params)
//ASSERT
val commands = Command.CreateObject(
prefilled = buildMap {
put(Relations.TYPE, typeDefault)
put(Relations.NAME, name)
},
template = null,
internalFlags = listOf()
)
verifyBlocking(repo, times(1)) { createObject(commands) }
}
private fun givenGetDefaultObjectType(type: String? = null, name: String? = null) {
getDefaultEditorType.stub {
onBlocking { run(Unit) } doReturn GetDefaultEditorType.Response(type, name)
}
}
private fun givenGetTemplates(objects: List<ObjectWrapper.Basic> = listOf()) {
getTemplates.stub {
onBlocking { run(any()) } doReturn objects
}
}
private fun stubCreateObject() {
repo.stub {
onBlocking { createObject(any()) } doReturn CreateObjectResult(
id = "",
event = Payload(context = "", events = listOf()),
details = null
)
}
}
}

View file

@ -0,0 +1,246 @@
package com.anytypeio.anytype.domain.page
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.CoroutineTestRule
import com.anytypeio.anytype.core_models.CreateObjectResult
import com.anytypeio.anytype.core_models.InternalFlags
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.templates.GetTemplates
import com.anytypeio.anytype.test_utils.MockDataFactory
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.stub
import com.nhaarman.mockitokotlin2.times
import com.nhaarman.mockitokotlin2.verifyBlocking
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.Mock
import org.mockito.junit.MockitoJUnit
import org.mockito.kotlin.verifyNoInteractions
class CreateObjectTest {
@get:Rule
val mockitoRule = MockitoJUnit.rule()
@ExperimentalCoroutinesApi
@get:Rule
var rule = CoroutineTestRule()
@Mock
lateinit var repo: BlockRepository
@Mock
lateinit var getDefaultEditorType: GetDefaultEditorType
@Mock
lateinit var getTemplates: GetTemplates
lateinit var createObject: CreateObject
@Before
fun setup() {
createObject = CreateObject(repo, getDefaultEditorType, getTemplates)
}
@Test
fun `when type is null and default type is null - should send proper params`() = runBlocking {
//SETUP
val type = null
givenGetDefaultObjectType()
stubCreateObject()
//TESTING
val params = CreateObject.Param(type)
createObject.run(params)
//ASSERT
verifyNoInteractions(getTemplates)
val commands = Command.CreateObject(
prefilled = emptyMap(),
template = null,
internalFlags = listOf(InternalFlags.ShouldSelectType, InternalFlags.ShouldEmptyDelete)
)
verifyBlocking(repo, times(1)) { createObject(commands) }
}
@Test
fun `when type is null and default type is note without template - should send proper params`() =
runBlocking {
//SETUP
val type = null
val defaultType = MockDataFactory.randomString()
val defaultTypeName = MockDataFactory.randomString()
givenGetDefaultObjectType(defaultType, defaultTypeName)
givenGetTemplates()
stubCreateObject()
//TESTING
val params = CreateObject.Param(type)
createObject.run(params)
//ASSERT
verifyBlocking(getTemplates, times(1)) { run(GetTemplates.Params(defaultType)) }
val commands = Command.CreateObject(
prefilled = buildMap { put(Relations.TYPE, defaultType) },
template = null,
internalFlags = listOf(
InternalFlags.ShouldSelectType,
InternalFlags.ShouldEmptyDelete
)
)
verifyBlocking(repo, times(1)) { createObject(commands) }
}
@Test
fun `when type is null and default type is book with template - should send proper params`() =
runBlocking {
//SETUP
val type = null
val defaultType = MockDataFactory.randomString()
val defaultTypeName = MockDataFactory.randomString()
val templateBook = MockDataFactory.randomString()
givenGetDefaultObjectType(defaultType, defaultTypeName)
givenGetTemplates(listOf(ObjectWrapper.Basic(buildMap {
put(Relations.ID, templateBook)
})))
stubCreateObject()
//TESTING
val params = CreateObject.Param(type)
createObject.run(params)
//ASSERT
verifyBlocking(getTemplates, times(1)) { run(GetTemplates.Params(defaultType)) }
val commands = Command.CreateObject(
prefilled = buildMap { put(Relations.TYPE, defaultType) },
template = templateBook,
internalFlags = listOf()
)
verifyBlocking(repo, times(1)) { createObject(commands) }
}
@Test
fun `when type is custom without template - should send proper params`() =
runBlocking {
//SETUP
val type = MockDataFactory.randomString()
givenGetTemplates()
stubCreateObject()
//TESTING
val params = CreateObject.Param(type)
createObject.run(params)
//ASSERT
verifyNoInteractions(getDefaultEditorType)
verifyBlocking(getTemplates, times(1)) { run(GetTemplates.Params(type)) }
val commands = Command.CreateObject(
prefilled = buildMap { put(Relations.TYPE, type) },
template = null,
internalFlags = listOf(
InternalFlags.ShouldSelectType,
InternalFlags.ShouldEmptyDelete
)
)
verifyBlocking(repo, times(1)) { createObject(commands) }
}
@Test
fun `when type is custom with one template - should send proper params`() =
runBlocking {
//SETUP
val type = MockDataFactory.randomString()
val template = MockDataFactory.randomString()
givenGetTemplates(listOf(ObjectWrapper.Basic(buildMap {
put(Relations.ID, template)
})))
stubCreateObject()
//TESTING
val params = CreateObject.Param(type)
createObject.run(params)
//ASSERT
verifyNoInteractions(getDefaultEditorType)
verifyBlocking(getTemplates, times(1)) { run(GetTemplates.Params(type)) }
val commands = Command.CreateObject(
prefilled = buildMap { put(Relations.TYPE, type) },
template = template,
internalFlags = listOf()
)
verifyBlocking(repo, times(1)) { createObject(commands) }
}
@Test
fun `when type is custom with two templates - should send proper params`() =
runBlocking {
//SETUP
val type = MockDataFactory.randomString()
val templateOne = MockDataFactory.randomString()
val templateTwo = MockDataFactory.randomString()
givenGetTemplates(
listOf(
ObjectWrapper.Basic(buildMap {
put(Relations.ID, templateOne)
}),
ObjectWrapper.Basic(buildMap {
put(Relations.ID, templateTwo)
})
)
)
stubCreateObject()
//TESTING
val params = CreateObject.Param(type)
createObject.run(params)
//ASSERT
verifyNoInteractions(getDefaultEditorType)
verifyBlocking(getTemplates, times(1)) { run(GetTemplates.Params(type)) }
val commands = Command.CreateObject(
prefilled = buildMap { put(Relations.TYPE, type) },
template = null,
internalFlags = listOf(
InternalFlags.ShouldSelectType,
InternalFlags.ShouldEmptyDelete
)
)
verifyBlocking(repo, times(1)) { createObject(commands) }
}
private fun givenGetDefaultObjectType(type: String? = null, name: String? = null) {
getDefaultEditorType.stub {
onBlocking { run(Unit) } doReturn GetDefaultEditorType.Response(type, name)
}
}
private fun givenGetTemplates(objects: List<ObjectWrapper.Basic> = listOf()) {
getTemplates.stub {
onBlocking { run(any()) } doReturn objects
}
}
private fun stubCreateObject() {
repo.stub {
onBlocking { createObject(any()) } doReturn CreateObjectResult(
id = "",
event = Payload(context = "", events = listOf()),
details = null
)
}
}
}

View file

@ -3,6 +3,8 @@ package com.anytypeio.anytype.middleware.block
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.CBTextStyle
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.CreateBlockLinkWithObjectResult
import com.anytypeio.anytype.core_models.CreateObjectResult
import com.anytypeio.anytype.core_models.DVFilter
import com.anytypeio.anytype.core_models.DVSort
import com.anytypeio.anytype.core_models.DVViewer
@ -40,24 +42,6 @@ class BlockMiddleware(
middleware.objectClose(id)
}
override suspend fun createPage(
ctx: Id?,
emoji: String?,
isDraft: Boolean?,
type: String?,
template: Id?
): String = middleware.blockLinkCreateWithObject(
ctx = ctx,
emoji = emoji,
isDraft = isDraft,
type = type,
template = template
)
override suspend fun createPage(
command: Command.CreateNewDocument
): String = middleware.objectCreate(command)
override suspend fun openPage(id: String): Payload = middleware.objectOpen(id)
override suspend fun openProfile(id: String): Payload = middleware.objectOpen(id)
override suspend fun openObjectSet(id: String): Payload = middleware.objectOpen(id)
@ -124,10 +108,6 @@ class BlockMiddleware(
command.prototype
)
override suspend fun createDocument(
command: Command.CreateDocument
): Triple<String, String, Payload> = middleware.blockLinkCreateWithObject(command)
override suspend fun duplicate(
command: Command.Duplicate
): Pair<List<Id>, Payload> = middleware.blockListDuplicate(command)
@ -313,16 +293,6 @@ class BlockMiddleware(
viewer = viewer
)
override suspend fun createDataViewObject(
type: Id,
template: Id?,
prefilled: Struct,
): Id = middleware.objectCreate(
template = template,
prefilled = prefilled,
type = type
)
override suspend fun addDataViewViewer(
ctx: String,
target: String,
@ -500,14 +470,14 @@ class BlockMiddleware(
ctx: String,
target: String,
position: Position,
rowCount: Int,
columnCount: Int
rows: Int,
columns: Int
): Payload = middleware.createTable(
ctx = ctx,
target = target,
position = position,
rowCount = rowCount,
columnCount = columnCount
rows = rows,
columns = columns
)
override suspend fun fillTableRow(ctx: String, targetIds: List<String>): Payload =
@ -689,4 +659,12 @@ class BlockMiddleware(
override suspend fun addObjectToWorkspace(objects: List<Id>): List<Id> {
return middleware.workspaceObjectListAdd(objects)
}
override suspend fun createObject(
command: Command.CreateObject
): CreateObjectResult = middleware.objectCreate(command)
override suspend fun createBlockLinkWithObject(
command: Command.CreateBlockLinkWithObject
): CreateBlockLinkWithObjectResult = middleware.blockLinkCreateWithObject(command)
}

View file

@ -2,7 +2,6 @@ package com.anytypeio.anytype.middleware.interactor
import anytype.Rpc
import anytype.model.Block
import anytype.model.InternalFlag
import anytype.model.ObjectInfo
import anytype.model.ObjectInfoWithLinks
import anytype.model.Range
@ -10,6 +9,8 @@ import com.anytypeio.anytype.core_models.AccountSetup
import com.anytypeio.anytype.core_models.AccountStatus
import com.anytypeio.anytype.core_models.CBTextStyle
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.CreateBlockLinkWithObjectResult
import com.anytypeio.anytype.core_models.CreateObjectResult
import com.anytypeio.anytype.core_models.DVFilter
import com.anytypeio.anytype.core_models.DVSort
import com.anytypeio.anytype.core_models.DVViewer
@ -33,6 +34,7 @@ import com.anytypeio.anytype.middleware.mappers.MRelation
import com.anytypeio.anytype.middleware.mappers.MRelationFormat
import com.anytypeio.anytype.middleware.mappers.core
import com.anytypeio.anytype.middleware.mappers.parse
import com.anytypeio.anytype.middleware.mappers.toCoreModel
import com.anytypeio.anytype.middleware.mappers.toCoreModels
import com.anytypeio.anytype.middleware.mappers.toMiddlewareModel
import com.anytypeio.anytype.middleware.mappers.toPayload
@ -315,78 +317,6 @@ class Middleware(
return response.event.toPayload()
}
@Throws(Exception::class)
fun blockLinkCreateWithObject(
ctx: Id?,
emoji: String?,
isDraft: Boolean?,
type: String?,
template: Id?
): Id {
val details: MutableMap<String, Any> = mutableMapOf()
emoji?.let { details[Relations.ICON_EMOJI] = it }
isDraft?.let { details[Relations.IS_DRAFT] = it }
type?.let { details[Relations.TYPE] = it }
val flags = buildList {
if (isDraft == true)
add(InternalFlag(InternalFlag.Value.editorDeleteEmpty))
}
val request = Rpc.BlockLink.CreateWithObject.Request(
contextId = ctx.orEmpty(),
details = details,
position = Block.Position.Inner,
templateId = template.orEmpty(),
internalFlags = flags
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockLinkCreateWithObject(request)
if (BuildConfig.DEBUG) logResponse(response)
return response.targetId
}
@Throws(Exception::class)
fun blockLinkCreateWithObject(command: Command.CreateDocument): Triple<String, String, Payload> {
val details: MutableMap<String, Any> = mutableMapOf()
command.emoji?.let { details[Relations.ICON_EMOJI] = it }
command.type?.let { details[Relations.TYPE] = it }
command.layout?.let { details[Relations.LAYOUT] = it.toMiddlewareModel().value.toDouble() }
val position: Block.Position = command.position.toMiddlewareModel()
val flags = buildList<InternalFlag> {
// Add flags when needed
}
val request = Rpc.BlockLink.CreateWithObject.Request(
contextId = command.context,
targetId = command.target,
position = position,
details = details,
templateId = command.template.orEmpty(),
internalFlags = flags
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockLinkCreateWithObject(request)
if (BuildConfig.DEBUG) logResponse(response)
return Triple(
response.blockId,
response.targetId,
response.event.toPayload()
)
}
@Throws(Exception::class)
fun blockListDelete(command: Command.Unlink): Payload {
val request = Rpc.Block.ListDelete.Request(
@ -914,50 +844,38 @@ class Middleware(
@Throws(Exception::class)
fun objectCreate(
type: Id,
template: Id?,
prefilled: Struct,
shouldSelectType: Boolean = false,
shouldEmptyDelete: Boolean = false
) : Id {
val details: Struct = buildMap {
put(Relations.TYPE, type)
putAll(prefilled)
}
val flags = buildList {
if (shouldSelectType) add(InternalFlag(InternalFlag.Value.editorSelectType))
if (shouldEmptyDelete) add(InternalFlag(InternalFlag.Value.editorDeleteEmpty))
}
command: Command.CreateObject
): CreateObjectResult {
val request = Rpc.Object.Create.Request(
details = details.toMap(),
templateId = template.orEmpty(),
internalFlags = flags
details = command.prefilled,
templateId = command.template.orEmpty(),
internalFlags = command.internalFlags.toMiddlewareModel()
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.objectCreate(request)
if (BuildConfig.DEBUG) logResponse(response)
return response.objectId
return response.toCoreModel()
}
@Throws(Exception::class)
fun objectCreate(command: Command.CreateNewDocument): Id {
TODO("relations refactoring")
// val details: Map<String, Any> = buildMap {
// command.emoji?.let { put(Relations.ICON_EMOJI, it) }
// command.name.let { put(Relations.NAME, it) }
// command.type?.let { put(Relations.TYPE, it) }
// }
// val flags = buildList<InternalFlag> {
//
// }
// val request = Rpc.Object.Create.Request(
// details = details.toMap(),
// internalFlags = flags
// )
// if (BuildConfig.DEBUG) logRequest(request)
// val response = service.objectCreate(request)
// if (BuildConfig.DEBUG) logResponse(response)
// return response.pageId
fun blockLinkCreateWithObject(
command: Command.CreateBlockLinkWithObject
): CreateBlockLinkWithObjectResult {
val request = Rpc.BlockLink.CreateWithObject.Request(
contextId = command.context,
details = command.prefilled,
templateId = command.template.orEmpty(),
internalFlags = command.internalFlags.toMiddlewareModel(),
targetId = command.target,
position = command.position.toMiddlewareModel(),
fields = null
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.blockLinkCreateWithObject(request)
if (BuildConfig.DEBUG) logResponse(response)
return response.toCoreModel()
}
@Throws(Exception::class)
@ -988,7 +906,7 @@ class Middleware(
format: RelationFormat,
formatObjectTypes: List<Id>,
prefilled: Struct
) : ObjectWrapper.Relation {
): ObjectWrapper.Relation {
val request = Rpc.Object.CreateRelation.Request(
details = buildMap {
put(Relations.NAME, name)
@ -1015,7 +933,7 @@ class Middleware(
relation: Key,
name: String,
color: String
) : ObjectWrapper.Option {
): ObjectWrapper.Option {
val request = Rpc.Object.CreateRelationOption.Request(
details = buildMap {
put(Relations.RELATION_KEY, relation)
@ -1606,15 +1524,15 @@ class Middleware(
ctx: String,
target: String,
position: Position,
rowCount: Int,
columnCount: Int
rows: Int,
columns: Int
): Payload {
val request = Rpc.BlockTable.Create.Request(
contextId = ctx,
targetId = target,
position = position.toMiddlewareModel(),
rows = rowCount,
columns = columnCount
rows = rows,
columns = columns
)
if (BuildConfig.DEBUG) logRequest(request)
val response = service.createTable(request)

View file

@ -1,6 +1,7 @@
package com.anytypeio.anytype.middleware.mappers
import anytype.ResponseEvent
import anytype.Rpc
import anytype.model.ObjectInfo
import anytype.model.ObjectInfoWithLinks
import anytype.model.ObjectLinksInfo
@ -707,4 +708,20 @@ fun MAccountStatus.core(): AccountStatus = when (statusType) {
)
MAccountStatusType.StartedDeletion -> AccountStatus.Deleted
MAccountStatusType.Deleted -> AccountStatus.Deleted
}
fun Rpc.Object.Create.Response.toCoreModel(): CreateObjectResult {
return CreateObjectResult(
id = objectId,
event = event.toPayload(),
details = details
)
}
fun Rpc.BlockLink.CreateWithObject.Response.toCoreModel(): CreateBlockLinkWithObjectResult {
return CreateBlockLinkWithObjectResult(
blockId = blockId,
objectId = targetId,
event = event.toPayload()
)
}

View file

@ -1,9 +1,11 @@
package com.anytypeio.anytype.middleware.mappers
import anytype.model.InternalFlag
import anytype.model.Range
import anytype.model.RelationFormat
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.BlockSplitMode
import com.anytypeio.anytype.core_models.InternalFlags
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.Position
import com.anytypeio.anytype.core_models.Relation
@ -363,20 +365,21 @@ fun Block.Content.DataView.Filter.Operator.toMiddlewareModel(): MDVFilterOperato
Block.Content.DataView.Filter.Operator.OR -> MDVFilterOperator.Or
}
fun Block.Content.DataView.Filter.QuickOption.toMiddlewareModel(): MDVFilterQuickOption = when (this) {
Block.Content.DataView.Filter.QuickOption.EXACT_DATE -> MDVFilterQuickOption.ExactDate
Block.Content.DataView.Filter.QuickOption.YESTERDAY -> MDVFilterQuickOption.Yesterday
Block.Content.DataView.Filter.QuickOption.TODAY -> MDVFilterQuickOption.Today
Block.Content.DataView.Filter.QuickOption.TOMORROW -> MDVFilterQuickOption.Tomorrow
Block.Content.DataView.Filter.QuickOption.LAST_WEEK -> MDVFilterQuickOption.LastWeek
Block.Content.DataView.Filter.QuickOption.CURRENT_WEEK -> MDVFilterQuickOption.CurrentWeek
Block.Content.DataView.Filter.QuickOption.NEXT_WEEK -> MDVFilterQuickOption.NextWeek
Block.Content.DataView.Filter.QuickOption.LAST_MONTH -> MDVFilterQuickOption.LastMonth
Block.Content.DataView.Filter.QuickOption.CURRENT_MONTH -> MDVFilterQuickOption.CurrentMonth
Block.Content.DataView.Filter.QuickOption.NEXT_MONTH -> MDVFilterQuickOption.NextMonth
Block.Content.DataView.Filter.QuickOption.DAYS_AGO -> MDVFilterQuickOption.NumberOfDaysAgo
Block.Content.DataView.Filter.QuickOption.DAYS_AHEAD -> MDVFilterQuickOption.NumberOfDaysNow
}
fun Block.Content.DataView.Filter.QuickOption.toMiddlewareModel(): MDVFilterQuickOption =
when (this) {
Block.Content.DataView.Filter.QuickOption.EXACT_DATE -> MDVFilterQuickOption.ExactDate
Block.Content.DataView.Filter.QuickOption.YESTERDAY -> MDVFilterQuickOption.Yesterday
Block.Content.DataView.Filter.QuickOption.TODAY -> MDVFilterQuickOption.Today
Block.Content.DataView.Filter.QuickOption.TOMORROW -> MDVFilterQuickOption.Tomorrow
Block.Content.DataView.Filter.QuickOption.LAST_WEEK -> MDVFilterQuickOption.LastWeek
Block.Content.DataView.Filter.QuickOption.CURRENT_WEEK -> MDVFilterQuickOption.CurrentWeek
Block.Content.DataView.Filter.QuickOption.NEXT_WEEK -> MDVFilterQuickOption.NextWeek
Block.Content.DataView.Filter.QuickOption.LAST_MONTH -> MDVFilterQuickOption.LastMonth
Block.Content.DataView.Filter.QuickOption.CURRENT_MONTH -> MDVFilterQuickOption.CurrentMonth
Block.Content.DataView.Filter.QuickOption.NEXT_MONTH -> MDVFilterQuickOption.NextMonth
Block.Content.DataView.Filter.QuickOption.DAYS_AGO -> MDVFilterQuickOption.NumberOfDaysAgo
Block.Content.DataView.Filter.QuickOption.DAYS_AHEAD -> MDVFilterQuickOption.NumberOfDaysNow
}
fun Block.Content.DataView.Filter.Condition.toMiddlewareModel(): MDVFilterCondition = when (this) {
Block.Content.DataView.Filter.Condition.EQUAL -> MDVFilterCondition.Equal
@ -457,4 +460,12 @@ fun Relation.Format.toMiddlewareModel(): MRelationFormat = when (this) {
Relation.Format.TAG -> MRelationFormat.tag
Relation.Format.RELATIONS -> MRelationFormat.relations
Relation.Format.UNDEFINED -> throw IllegalStateException("Format was undefined")
}
fun List<InternalFlags>.toMiddlewareModel(): List<InternalFlag> = map {
when (it) {
InternalFlags.ShouldEmptyDelete -> InternalFlag(InternalFlag.Value.editorDeleteEmpty)
InternalFlags.ShouldSelectTemplate -> InternalFlag(InternalFlag.Value.editorSelectTemplate)
InternalFlags.ShouldSelectType -> InternalFlag(InternalFlag.Value.editorSelectType)
}
}

View file

@ -7,6 +7,7 @@ import anytype.model.Range
import com.anytypeio.anytype.core_models.BlockSplitMode
import com.anytypeio.anytype.core_models.Command
import com.anytypeio.anytype.core_models.Position
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.middleware.interactor.Middleware
import com.anytypeio.anytype.middleware.interactor.MiddlewareFactory
import com.anytypeio.anytype.middleware.service.MiddlewareService
@ -70,13 +71,15 @@ class MiddlewareTest {
// SETUP
val command = Command.CreateDocument(
val templateId = MockDataFactory.randomUuid()
val command = Command.CreateBlockLinkWithObject(
context = MockDataFactory.randomUuid(),
target = MockDataFactory.randomUuid(),
position = Position.INNER,
emoji = null,
type = null,
layout = null
template = templateId,
prefilled = emptyMap(),
internalFlags = listOf()
)
val response = Rpc.BlockLink.CreateWithObject.Response(
@ -89,7 +92,8 @@ class MiddlewareTest {
contextId = command.context,
targetId = command.target,
position = Block.Position.Inner,
details = mapOf<String, Any?>()
details = mapOf<String, Any?>(),
templateId = templateId
)
service.stub {
@ -114,19 +118,19 @@ class MiddlewareTest {
}
@Test
fun `should create request to create new document with emoji`() {
fun `should create request to create new document with name`() {
// SETUP
val emoji = "🎒"
val name = MockDataFactory.randomString()
val command = Command.CreateDocument(
val command = Command.CreateBlockLinkWithObject(
context = MockDataFactory.randomUuid(),
target = MockDataFactory.randomUuid(),
position = Position.INNER,
emoji = emoji,
type = null,
layout = null
template = null,
prefilled = buildMap { put(Relations.NAME, name) },
internalFlags = listOf()
)
val response = Rpc.BlockLink.CreateWithObject.Response(
@ -139,7 +143,7 @@ class MiddlewareTest {
contextId = command.context,
targetId = command.target,
position = Block.Position.Inner,
details = mapOf("iconEmoji" to emoji)
details = buildMap { put(Relations.NAME, name) }
)
service.stub {

View file

@ -39,7 +39,7 @@ import com.anytypeio.anytype.domain.objects.DeleteObjects
import com.anytypeio.anytype.domain.objects.ObjectStore
import com.anytypeio.anytype.domain.objects.SetObjectListIsArchived
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.CancelSearchSubscription
import com.anytypeio.anytype.domain.search.ObjectSearchSubscriptionContainer
import com.anytypeio.anytype.domain.search.SearchObjects
@ -90,7 +90,7 @@ class HomeDashboardViewModel(
private val cancelSearchSubscription: CancelSearchSubscription,
private val objectStore: ObjectStore,
private val storeOfObjectTypes: StoreOfObjectTypes,
private val createNewObject: CreateNewObject,
private val createObject: CreateObject,
featureToggles: FeatureToggles
) : ViewStateViewModel<State>(),
HomeDashboardEventConverter by eventConverter,
@ -274,12 +274,12 @@ class HomeDashboardViewModel(
fun onAddNewDocumentClicked() {
Timber.d("onAddNewDocumentClicked, ")
subscriptions += viewModelScope.launch {
createNewObject.execute(Unit).fold(
onSuccess = { id ->
createObject.execute(CreateObject.Param(type = null)).fold(
onSuccess = { result ->
machine.onEvents(listOf(Machine.Event.OnFinishedCreatingPage))
proceedWithOpeningDocument(id)
proceedWithOpeningDocument(result.objectId)
},
onFailure = { e -> Timber.e(e, "Error while creating a new page") }
onFailure = { e -> Timber.e(e, "Error while creating a new object") }
)
}
}

View file

@ -16,7 +16,7 @@ import com.anytypeio.anytype.domain.objects.DeleteObjects
import com.anytypeio.anytype.domain.objects.ObjectStore
import com.anytypeio.anytype.domain.objects.SetObjectListIsArchived
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.CancelSearchSubscription
import com.anytypeio.anytype.domain.search.ObjectSearchSubscriptionContainer
import com.anytypeio.anytype.domain.search.SearchObjects
@ -39,7 +39,7 @@ class HomeDashboardViewModelFactory(
private val cancelSearchSubscription: CancelSearchSubscription,
private val objectStore: ObjectStore,
private val featureToggles: FeatureToggles,
private val createNewObject: CreateNewObject,
private val createObject: CreateObject,
private val storeOfObjectTypes: StoreOfObjectTypes
) : ViewModelProvider.Factory {
@ -62,7 +62,7 @@ class HomeDashboardViewModelFactory(
objectSearchSubscriptionContainer = objectSearchSubscriptionContainer,
cancelSearchSubscription = cancelSearchSubscription,
objectStore = objectStore,
createNewObject = createNewObject,
createObject = createObject,
featureToggles = featureToggles,
storeOfObjectTypes = storeOfObjectTypes
) as T

View file

@ -70,9 +70,8 @@ import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.domain.page.CloseBlock
import com.anytypeio.anytype.domain.page.CreateDocument
import com.anytypeio.anytype.domain.page.CreateNewDocument
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreateObjectAsMentionOrLink
import com.anytypeio.anytype.domain.page.CreateBlockLinkWithObject
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.page.OpenPage
import com.anytypeio.anytype.domain.search.SearchObjects
@ -240,9 +239,8 @@ import com.anytypeio.anytype.presentation.editor.Editor.Mode as EditorMode
class EditorViewModel(
private val openPage: OpenPage,
private val closePage: CloseBlock,
private val createDocument: CreateDocument,
private val createObject: CreateObject,
private val createNewDocument: CreateNewDocument,
private val createBlockLinkWithObject: CreateBlockLinkWithObject,
private val createObjectAsMentionOrLink: CreateObjectAsMentionOrLink,
private val interceptEvents: InterceptEvents,
private val interceptThreadStatus: InterceptThreadStatus,
private val updateLinkMarks: UpdateLinkMarks,
@ -265,7 +263,7 @@ class EditorViewModel(
private val setDocCoverImage: SetDocCoverImage,
private val setDocImageIcon: SetDocumentImageIcon,
private val templateDelegate: EditorTemplateDelegate,
private val createNewObject: CreateNewObject,
private val createObject: CreateObject,
private val objectToSet: ConvertObjectToSet,
private val storeOfRelations: StoreOfRelations,
private val storeOfObjectTypes: StoreOfObjectTypes,
@ -3026,22 +3024,23 @@ class EditorViewModel(
position = Position.BOTTOM
}
val params = CreateObject.Params(
val params = CreateBlockLinkWithObject.Params(
context = context,
position = position,
target = target,
type = type,
layout = null
type = type
)
val startTime = System.currentTimeMillis()
viewModelScope.launch {
createObject(
createBlockLinkWithObject.execute(
params = params
).proceed(
failure = { Timber.e(it, "Error while creating new object with params: $params") },
success = { result ->
).fold(
onFailure = {
Timber.e(it, "Error while creating new object with params: $params")
},
onSuccess = { result ->
val middleTime = System.currentTimeMillis()
orchestrator.proxies.payloads.send(result.payload)
sendAnalyticsObjectCreateEvent(
@ -3053,7 +3052,7 @@ class EditorViewModel(
middleTime = middleTime,
context = analyticsContext
)
proceedWithOpeningObject(result.target)
proceedWithOpeningObject(result.objectId)
}
)
}
@ -3071,53 +3070,11 @@ class EditorViewModel(
)
jobs += viewModelScope.launch {
createNewObject.execute(Unit).fold(
onSuccess = { id ->
proceedWithOpeningObject(id)
},
onFailure = { e -> Timber.e(e, "Error while creating a new page") }
)
}
}
@Deprecated("Not used")
fun onAddNewPageClicked() {
Timber.d("onAddNewPageClicked, ")
controlPanelInteractor.onEvent(ControlPanelMachine.Event.OnAddBlockToolbarOptionSelected)
val position: Position
val focused = blocks.first { it.id == orchestrator.stores.focus.current().id }
var target = focused.id
if (focused.id == context) {
if (focused.children.isEmpty())
position = Position.INNER
else {
position = Position.TOP
target = focused.children.first()
}
} else {
position = Position.BOTTOM
}
val params = CreateDocument.Params(
context = context,
position = position,
target = target
)
viewModelScope.launch {
createDocument(
params = params
).proceed(
failure = { Timber.e(it, "Error while creating new page with params: $params") },
success = { result ->
orchestrator.proxies.payloads.send(result.payload)
proceedWithOpeningObject(result.target)
}
)
createObject.execute(CreateObject.Param(type = null))
.fold(
onSuccess = { result -> proceedWithOpeningObject(result.objectId) },
onFailure = { e -> Timber.e(e, "Error while creating a new page") }
)
}
}
@ -5520,7 +5477,7 @@ class EditorViewModel(
}
private fun proceedWithCreateNewObject(objectType: String?, mentionText: String) {
val params = CreateNewDocument.Params(
val params = CreateObjectAsMentionOrLink.Params(
name = mentionText.removePrefix(MENTION_PREFIX),
type = objectType
)
@ -5528,13 +5485,13 @@ class EditorViewModel(
val startTime = System.currentTimeMillis()
viewModelScope.launch {
createNewDocument(
createObjectAsMentionOrLink.execute(
params = params
).proceed(
failure = {
).fold(
onFailure = {
Timber.e(it, "Error while creating new page with params: $params")
},
success = { result ->
onSuccess = { result ->
val middleTime = System.currentTimeMillis()
onCreateMentionInText(
id = result.id,
@ -5945,10 +5902,10 @@ class EditorViewModel(
private suspend fun createObjectAddProceedToAddToTextAsLink(name: String, type: String?) {
val startTime = System.currentTimeMillis()
val params = CreateNewDocument.Params(name, type)
createNewDocument.invoke(params).process(
failure = { Timber.e(it, "Error while creating new page with params: $params") },
success = { result ->
val params = CreateObjectAsMentionOrLink.Params(name, type)
createObjectAsMentionOrLink.execute(params).fold(
onFailure = { Timber.e(it, "Error while creating new page with params: $params") },
onSuccess = { result ->
val middleTime = System.currentTimeMillis()
proceedToAddObjectToTextAsLink(id = result.id)
// val objType = objectTypesProvider.get().firstOrNull { it.url == type }

View file

@ -20,9 +20,8 @@ import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.domain.page.CloseBlock
import com.anytypeio.anytype.domain.page.CreateDocument
import com.anytypeio.anytype.domain.page.CreateNewDocument
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreateObjectAsMentionOrLink
import com.anytypeio.anytype.domain.page.CreateBlockLinkWithObject
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.page.OpenPage
import com.anytypeio.anytype.domain.search.SearchObjects
@ -43,10 +42,9 @@ import com.anytypeio.anytype.presentation.util.Dispatcher
open class EditorViewModelFactory(
private val openPage: OpenPage,
private val closeObject: CloseBlock,
private val createDocument: CreateDocument,
private val createObjectSet: CreateObjectSet,
private val createObject: CreateObject,
private val createNewDocument: CreateNewDocument,
private val createBlockLinkWithObject: CreateBlockLinkWithObject,
private val createObjectAsMentionOrLink: CreateObjectAsMentionOrLink,
private val interceptEvents: InterceptEvents,
private val interceptThreadStatus: InterceptThreadStatus,
private val updateLinkMarks: UpdateLinkMarks,
@ -68,7 +66,7 @@ open class EditorViewModelFactory(
private val setDocCoverImage: SetDocCoverImage,
private val setDocImageIcon: SetDocumentImageIcon,
private val editorTemplateDelegate: EditorTemplateDelegate,
private val createNewObject: CreateNewObject,
private val createObject: CreateObject,
private val objectToSet: ConvertObjectToSet,
private val storeOfRelations: StoreOfRelations,
private val storeOfObjectTypes: StoreOfObjectTypes,
@ -85,12 +83,11 @@ open class EditorViewModelFactory(
interceptThreadStatus = interceptThreadStatus,
updateLinkMarks = updateLinkMarks,
removeLinkMark = removeLinkMark,
createObject = createObject,
createBlockLinkWithObject = createBlockLinkWithObject,
reducer = documentEventReducer,
urlBuilder = urlBuilder,
renderer = renderer,
createDocument = createDocument,
createNewDocument = createNewDocument,
createObjectAsMentionOrLink = createObjectAsMentionOrLink,
orchestrator = orchestrator,
analytics = analytics,
dispatcher = dispatcher,
@ -106,7 +103,7 @@ open class EditorViewModelFactory(
setDocCoverImage = setDocCoverImage,
setDocImageIcon = setDocImageIcon,
templateDelegate = editorTemplateDelegate,
createNewObject = createNewObject,
createObject = createObject,
objectToSet = objectToSet,
storeOfRelations = storeOfRelations,
storeOfObjectTypes = storeOfObjectTypes,

View file

@ -4,13 +4,13 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.anytypeio.anytype.domain.base.fold
import com.anytypeio.anytype.domain.page.CreatePage
import com.anytypeio.anytype.domain.page.CreateObject
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import timber.log.Timber
class CreateObjectViewModel(private val createPage: CreatePage) : ViewModel() {
class CreateObjectViewModel(private val createObject: CreateObject) : ViewModel() {
val createObjectStatus = MutableSharedFlow<State>(replay = 0)
private val jobs = mutableListOf<Job>()
@ -20,19 +20,14 @@ class CreateObjectViewModel(private val createPage: CreatePage) : ViewModel() {
}
private fun onCreatePage(type: String) {
val params = CreatePage.Params(
ctx = null,
isDraft = true,
type = type,
emoji = null
)
val params = CreateObject.Param(type = type)
jobs += viewModelScope.launch {
createPage.execute(params).fold(
createObject.execute(params).fold(
onFailure = { e ->
Timber.e(e, "Error while creating a new page")
Timber.e(e, "Error while creating a new object with type:$type")
},
onSuccess = { id ->
createObjectStatus.emit(State.Success(id))
onSuccess = { result ->
createObjectStatus.emit(State.Success(result.objectId))
}
)
}
@ -53,12 +48,12 @@ class CreateObjectViewModel(private val createPage: CreatePage) : ViewModel() {
}
class Factory(
private val createPage: CreatePage
private val createObject: CreateObject
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return CreateObjectViewModel(createPage = createPage) as T
return CreateObjectViewModel(createObject = createObject) as T
}
}
}

View file

@ -38,7 +38,7 @@ import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.domain.page.CloseBlock
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.CancelSearchSubscription
import com.anytypeio.anytype.domain.search.DataViewSubscriptionContainer
import com.anytypeio.anytype.domain.sets.OpenObjectSet
@ -104,7 +104,7 @@ class ObjectSetViewModel(
private val session: ObjectSetSession,
private val analytics: Analytics,
private val createDataViewObject: CreateDataViewObject,
private val createNewObject: CreateNewObject,
private val createObject: CreateObject,
private val dataViewSubscriptionContainer: DataViewSubscriptionContainer,
private val cancelSearchSubscription: CancelSearchSubscription,
private val setDataViewSource: SetDataViewSource,
@ -199,7 +199,7 @@ class ObjectSetViewModel(
DataViewSubscriptionContainer.Params(
subscription = context,
sorts = view.sorts,
filters = view.filters.map { f : DVFilter ->
filters = view.filters.map { f: DVFilter ->
val r = storeOfRelations.getByKey(f.relationKey)
if (r != null && r.relationFormat == RelationFormat.DATE) {
f.copy(
@ -750,7 +750,7 @@ class ObjectSetViewModel(
} else {
val sourceDetails = currentState.details[sourceId]
if (sourceDetails != null && sourceDetails.map.isNotEmpty()) {
when(sourceDetails.type.firstOrNull()) {
when (sourceDetails.type.firstOrNull()) {
ObjectTypeIds.OBJECT_TYPE -> {
if (sourceId == ObjectTypeIds.BOOKMARK) {
dispatch(
@ -1100,11 +1100,14 @@ class ObjectSetViewModel(
props = Props(mapOf(EventsPropertiesKey.context to analyticsContext))
)
jobs += viewModelScope.launch {
createNewObject.execute(Unit).fold(
onSuccess = { id ->
proceedWithOpeningObject(id)
createObject.execute(CreateObject.Param(type = null)).fold(
onSuccess = { result ->
proceedWithOpeningObject(result.objectId)
},
onFailure = { e -> Timber.e(e, "Error while creating a new page") }
onFailure = { e ->
Timber.e(e, "Error while creating a new object")
toast("Error while creating a new object")
}
)
}
}

View file

@ -14,7 +14,7 @@ import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.domain.page.CloseBlock
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.CancelSearchSubscription
import com.anytypeio.anytype.domain.search.DataViewSubscriptionContainer
import com.anytypeio.anytype.domain.sets.OpenObjectSet
@ -43,7 +43,7 @@ class ObjectSetViewModelFactory(
private val urlBuilder: UrlBuilder,
private val session: ObjectSetSession,
private val analytics: Analytics,
private val createNewObject: CreateNewObject,
private val createObject: CreateObject,
private val dataViewSubscriptionContainer: DataViewSubscriptionContainer,
private val cancelSearchSubscription: CancelSearchSubscription,
private val setDataViewSource: SetDataViewSource,
@ -71,7 +71,7 @@ class ObjectSetViewModelFactory(
urlBuilder = urlBuilder,
session = session,
analytics = analytics,
createNewObject = createNewObject,
createObject = createObject,
dataViewSubscriptionContainer = dataViewSubscriptionContainer,
cancelSearchSubscription = cancelSearchSubscription,
setDataViewSource = setDataViewSource,

View file

@ -23,7 +23,7 @@ import com.anytypeio.anytype.domain.base.fold
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.launch.SetDefaultEditorType
import com.anytypeio.anytype.domain.misc.AppActionManager
import com.anytypeio.anytype.domain.page.CreatePage
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.ObjectTypesSubscriptionManager
import com.anytypeio.anytype.domain.search.RelationsSubscriptionManager
import com.anytypeio.anytype.presentation.objects.SupportedLayouts
@ -44,7 +44,7 @@ class SplashViewModel(
private val getLastOpenedObject: GetLastOpenedObject,
private val getDefaultEditorType: GetDefaultEditorType,
private val setDefaultEditorType: SetDefaultEditorType,
private val createPage: CreatePage,
private val createObject: CreateObject,
private val appActionManager: AppActionManager,
private val relationsSubscriptionManager: RelationsSubscriptionManager,
private val objectTypesSubscriptionManager: ObjectTypesSubscriptionManager
@ -187,19 +187,15 @@ class SplashViewModel(
fun onIntentCreateNewObject(type: Id) {
viewModelScope.launch {
createPage.execute(
CreatePage.Params(
ctx = null,
emoji = null,
isDraft = true,
type = type
)
createObject.execute(
CreateObject.Param(type = type)
).fold(
onFailure = { e ->
Timber.e(e, "Error while creating a new object with type:$type")
proceedWithNavigation()
},
onSuccess = { target ->
commands.emit(Command.NavigateToObject(target))
onSuccess = { result ->
commands.emit(Command.NavigateToObject(result.objectId))
}
)
}

View file

@ -10,7 +10,7 @@ import com.anytypeio.anytype.domain.auth.interactor.LaunchWallet
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.launch.SetDefaultEditorType
import com.anytypeio.anytype.domain.misc.AppActionManager
import com.anytypeio.anytype.domain.page.CreatePage
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.ObjectTypesSubscriptionManager
import com.anytypeio.anytype.domain.search.RelationsSubscriptionManager
@ -28,7 +28,7 @@ class SplashViewModelFactory(
private val getDefaultEditorType: GetDefaultEditorType,
private val setDefaultEditorType: SetDefaultEditorType,
private val appActionManager: AppActionManager,
private val createPage: CreatePage,
private val createObject: CreateObject,
private val relationsSubscriptionManager: RelationsSubscriptionManager,
private val objectTypesSubscriptionManager: ObjectTypesSubscriptionManager
) : ViewModelProvider.Factory {
@ -44,7 +44,7 @@ class SplashViewModelFactory(
getDefaultEditorType = getDefaultEditorType,
setDefaultEditorType = setDefaultEditorType,
appActionManager = appActionManager,
createPage = createPage,
createObject = createObject,
relationsSubscriptionManager = relationsSubscriptionManager,
objectTypesSubscriptionManager = objectTypesSubscriptionManager
) as T

View file

@ -27,7 +27,7 @@ import com.anytypeio.anytype.domain.objects.DefaultStoreOfObjectTypes
import com.anytypeio.anytype.domain.objects.DeleteObjects
import com.anytypeio.anytype.domain.objects.ObjectStore
import com.anytypeio.anytype.domain.objects.SetObjectListIsArchived
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.CancelSearchSubscription
import com.anytypeio.anytype.domain.search.ObjectSearchSubscriptionContainer
import com.anytypeio.anytype.domain.search.SearchObjects
@ -105,7 +105,7 @@ open class DashboardTestSetup {
lateinit var getTemplates: GetTemplates
@Mock
lateinit var createNewObject: CreateNewObject
lateinit var createObject: CreateObject
private lateinit var objectStore: ObjectStore
@ -148,7 +148,7 @@ open class DashboardTestSetup {
main = coroutineTestRule.testDispatcher
)
),
createNewObject = createNewObject,
createObject = createObject,
featureToggles = mock(),
storeOfObjectTypes = storeOfObjectTypes
)

View file

@ -27,7 +27,7 @@ import com.anytypeio.anytype.domain.objects.DefaultStoreOfObjectTypes
import com.anytypeio.anytype.domain.objects.DeleteObjects
import com.anytypeio.anytype.domain.objects.ObjectStore
import com.anytypeio.anytype.domain.objects.SetObjectListIsArchived
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.CancelSearchSubscription
import com.anytypeio.anytype.domain.search.ObjectSearchSubscriptionContainer
import com.anytypeio.anytype.domain.search.SearchObjects
@ -117,7 +117,7 @@ class HomeDashboardViewModelTest {
lateinit var objectStore: ObjectStore
@Mock
lateinit var createNewObject: CreateNewObject
lateinit var createObject: CreateObject
private lateinit var vm: HomeDashboardViewModel
@ -153,7 +153,7 @@ class HomeDashboardViewModelTest {
cancelSearchSubscription = cancelSearchSubscription,
objectStore = objectStore,
objectSearchSubscriptionContainer = objectSearchSubscriptionContainer,
createNewObject = createNewObject,
createObject = createObject,
featureToggles = mock(),
storeOfObjectTypes = storeOfObjectTypes
)
@ -371,8 +371,16 @@ class HomeDashboardViewModelTest {
}
private fun givenDelegateId(id: String) {
createNewObject.stub {
onBlocking { execute(Unit) } doReturn Resultat.success(id)
createObject.stub {
onBlocking { execute(CreateObject.Param(null)) } doReturn Resultat.success(
CreateObject.Result(
objectId = id,
event = Payload(
context = id,
events = listOf()
)
)
)
}
}

View file

@ -66,9 +66,8 @@ import com.anytypeio.anytype.domain.objects.DefaultStoreOfRelations
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.domain.page.CloseBlock
import com.anytypeio.anytype.domain.page.CreateDocument
import com.anytypeio.anytype.domain.page.CreateNewDocument
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreateObjectAsMentionOrLink
import com.anytypeio.anytype.domain.page.CreateBlockLinkWithObject
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.page.OpenPage
import com.anytypeio.anytype.domain.page.Redo
@ -222,7 +221,7 @@ open class EditorViewModelTest {
lateinit var splitBlock: SplitBlock
@Mock
lateinit var createObject: CreateObject
lateinit var createBlockLinkWithObject: CreateBlockLinkWithObject
@Mock
lateinit var updateAlignment: UpdateAlignment
@ -258,10 +257,7 @@ open class EditorViewModelTest {
lateinit var createBookmarkBlock: CreateBookmarkBlock
@Mock
lateinit var createDocument: CreateDocument
@Mock
lateinit var createNewDocument: CreateNewDocument
lateinit var createObjectAsMentionOrLink: CreateObjectAsMentionOrLink
@Mock
lateinit var replaceBlock: ReplaceBlock
@ -326,7 +322,7 @@ open class EditorViewModelTest {
private lateinit var editorTemplateDelegate: EditorTemplateDelegate
@Mock
lateinit var createNewObject: CreateNewObject
lateinit var createObject: CreateObject
@Mock
lateinit var createTable: CreateTable
@ -3947,9 +3943,8 @@ open class EditorViewModelTest {
vm = EditorViewModel(
openPage = openPage,
closePage = closePage,
createDocument = createDocument,
createObject = createObject,
createNewDocument = createNewDocument,
createObjectAsMentionOrLink = createObjectAsMentionOrLink,
interceptEvents = interceptEvents,
interceptThreadStatus = interceptThreadStatus,
updateLinkMarks = updateLinkMark,
@ -4020,7 +4015,7 @@ open class EditorViewModelTest {
setDocCoverImage = setDocCoverImage,
setDocImageIcon = setDocImageIcon,
templateDelegate = editorTemplateDelegate,
createNewObject = createNewObject,
createBlockLinkWithObject = createBlockLinkWithObject,
featureToggles = mock(),
objectToSet = objectToSet,
storeOfRelations = storeOfRelations,
@ -4523,8 +4518,16 @@ open class EditorViewModelTest {
}
private fun givenDelegateId(id: String) {
createNewObject.stub {
onBlocking { execute(Unit) } doReturn Resultat.success(id)
createObject.stub {
onBlocking { execute(CreateObject.Param(null)) } doReturn Resultat.success(
CreateObject.Result(
objectId = id,
event = Payload(
context = id,
events = listOf()
)
)
)
}
}
}

View file

@ -408,7 +408,7 @@ class EditorMarkupObjectTest : EditorPresentationTestSetup() {
val newObjectType = PAGE
val newObjectId = MockDataFactory.randomString()
val newObjectName = MockDataFactory.randomString()
stubCreateNewDocument(
stubCreateObjectAsMentionOrLink(
name = newObjectName,
type = newObjectType,
id = newObjectId

View file

@ -13,7 +13,7 @@ import com.anytypeio.anytype.domain.base.Result
import com.anytypeio.anytype.domain.base.Resultat
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
import com.anytypeio.anytype.domain.icon.DocumentEmojiIconProvider
import com.anytypeio.anytype.domain.page.CreateNewDocument
import com.anytypeio.anytype.domain.page.CreateObjectAsMentionOrLink
import com.anytypeio.anytype.presentation.BuildConfig
import com.anytypeio.anytype.presentation.editor.EditorViewModel
import com.anytypeio.anytype.presentation.editor.editor.control.ControlPanelState
@ -34,7 +34,6 @@ import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.stub
import org.mockito.kotlin.times
@ -323,19 +322,18 @@ class EditorMentionTest : EditorPresentationTestSetup() {
Mockito.`when`(documentEmojiIconProvider.random()).thenReturn(emoji)
createNewDocument.stub {
createObjectAsMentionOrLink.stub {
onBlocking {
invoke(
CreateNewDocument.Params(
execute(
CreateObjectAsMentionOrLink.Params(
name = newPageName,
type = ObjectTypeIds.NOTE
)
)
} doReturn Either.Right(
CreateNewDocument.Result(
} doReturn Resultat.success(
CreateObjectAsMentionOrLink.Result(
name = newPageName,
id = newPageId,
emoji = emoji
id = newPageId
)
)
}
@ -364,9 +362,9 @@ class EditorMentionTest : EditorPresentationTestSetup() {
)
}
verifyBlocking(createNewDocument, times(1)) {
invoke(
CreateNewDocument.Params(
verifyBlocking(createObjectAsMentionOrLink, times(1)) {
execute(
CreateObjectAsMentionOrLink.Params(
name = newPageName,
type = ObjectTypeIds.NOTE
)
@ -492,19 +490,18 @@ class EditorMentionTest : EditorPresentationTestSetup() {
Mockito.`when`(documentEmojiIconProvider.random()).thenReturn(emoji)
createNewDocument.stub {
createObjectAsMentionOrLink.stub {
onBlocking {
invoke(
CreateNewDocument.Params(
execute(
CreateObjectAsMentionOrLink.Params(
name = newPageName,
type = "_otarticle"
)
)
} doReturn Either.Right(
CreateNewDocument.Result(
} doReturn Resultat.success(
CreateObjectAsMentionOrLink.Result(
name = newPageName,
id = newPageId,
emoji = emoji
id = newPageId
)
)
}
@ -533,9 +530,9 @@ class EditorMentionTest : EditorPresentationTestSetup() {
)
}
verifyBlocking(createNewDocument, times(1)) {
invoke(
CreateNewDocument.Params(
verifyBlocking(createObjectAsMentionOrLink, times(1)) {
execute(
CreateObjectAsMentionOrLink.Params(
name = newPageName,
type = "_otarticle"
)

View file

@ -10,7 +10,6 @@ import com.anytypeio.anytype.core_models.Relation
import com.anytypeio.anytype.core_models.RelationLink
import com.anytypeio.anytype.core_models.restrictions.ObjectRestriction
import com.anytypeio.anytype.domain.`object`.ConvertObjectToSet
import com.anytypeio.anytype.domain.`object`.ObjectTypesProvider
import com.anytypeio.anytype.domain.`object`.UpdateDetail
import com.anytypeio.anytype.domain.base.Either
import com.anytypeio.anytype.domain.base.Result
@ -55,9 +54,8 @@ import com.anytypeio.anytype.domain.objects.DefaultStoreOfRelations
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.domain.page.CloseBlock
import com.anytypeio.anytype.domain.page.CreateDocument
import com.anytypeio.anytype.domain.page.CreateNewDocument
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreateObjectAsMentionOrLink
import com.anytypeio.anytype.domain.page.CreateBlockLinkWithObject
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.page.OpenPage
import com.anytypeio.anytype.domain.page.Redo
@ -107,7 +105,6 @@ import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flowOf
import org.mockito.Mock
import org.mockito.kotlin.any
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.stub
@ -171,7 +168,7 @@ open class EditorPresentationTestSetup {
lateinit var splitBlock: SplitBlock
@Mock
lateinit var createObject: CreateObject
lateinit var createBlockLinkWithObject: CreateBlockLinkWithObject
@Mock
lateinit var updateAlignment: UpdateAlignment
@ -209,14 +206,11 @@ open class EditorPresentationTestSetup {
@Mock
lateinit var createBookmarkBlock: CreateBookmarkBlock
@Mock
lateinit var createDocument: CreateDocument
@Mock
lateinit var setRelationKey: SetRelationKey
@Mock
lateinit var createNewDocument: CreateNewDocument
lateinit var createObjectAsMentionOrLink: CreateObjectAsMentionOrLink
@Mock
lateinit var replaceBlock: ReplaceBlock
@ -245,9 +239,6 @@ open class EditorPresentationTestSetup {
@Mock
lateinit var setObjectType: SetObjectType
@Mock
lateinit var objectTypesProvider: ObjectTypesProvider
@Mock
lateinit var searchObjects: SearchObjects
@ -267,7 +258,7 @@ open class EditorPresentationTestSetup {
lateinit var copyFileToCacheDirectory: CopyFileToCacheDirectory
@Mock
lateinit var createNewObject: CreateNewObject
lateinit var createObject: CreateObject
@Mock
lateinit var getTemplates: GetTemplates
@ -407,9 +398,8 @@ open class EditorPresentationTestSetup {
return EditorViewModel(
openPage = openPage,
closePage = closePage,
createDocument = createDocument,
createObject = createObject,
createNewDocument = createNewDocument,
createBlockLinkWithObject = createBlockLinkWithObject,
createObjectAsMentionOrLink = createObjectAsMentionOrLink,
interceptEvents = interceptEvents,
interceptThreadStatus = interceptThreadStatus,
updateLinkMarks = updateLinkMark,
@ -437,7 +427,7 @@ open class EditorPresentationTestSetup {
setDocCoverImage = setDocCoverImage,
setDocImageIcon = setDocImageIcon,
templateDelegate = editorTemplateDelegate,
createNewObject = createNewObject,
createObject = createObject,
featureToggles = mock(),
objectToSet = objectToSet,
storeOfRelations = storeOfRelations,
@ -578,14 +568,14 @@ open class EditorPresentationTestSetup {
}
}
fun stubCreateObject(root: String, target: String) {
createObject.stub {
fun stubCreateBlockLinkWithObject(root: String, target: String) {
createBlockLinkWithObject.stub {
onBlocking {
invoke(any())
} doReturn Either.Right(
CreateObject.Result(
execute(any())
} doReturn Resultat.success(
CreateBlockLinkWithObject.Result(
id = root,
target = target,
objectId = target,
payload = Payload(
context = root,
events = emptyList()
@ -695,11 +685,11 @@ open class EditorPresentationTestSetup {
}
}
fun stubCreateNewDocument(name: String, type: String, id: String) {
val params = CreateNewDocument.Params(name, type)
val result = CreateNewDocument.Result(id, name, null)
createNewDocument.stub {
onBlocking { invoke(params) } doReturn Either.Right(result)
fun stubCreateObjectAsMentionOrLink(name: String, type: String, id: String) {
val params = CreateObjectAsMentionOrLink.Params(name, type)
val result = CreateObjectAsMentionOrLink.Result(id, name)
createObjectAsMentionOrLink.stub {
onBlocking { execute(params) } doReturn Resultat.success(result)
}
}

View file

@ -2,7 +2,7 @@ package com.anytypeio.anytype.presentation.editor.editor
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.anytypeio.anytype.core_models.Position
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.page.CreateBlockLinkWithObject
import com.anytypeio.anytype.presentation.MockTypicalDocumentFactory
import com.anytypeio.anytype.presentation.editor.EditorViewModel.Companion.TEXT_CHANGES_DEBOUNCE_DURATION
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types
@ -38,7 +38,7 @@ class EditorSlashWidgetObjectTypeTest : EditorPresentationTestSetup() {
}
@Test
fun `should invoke createObject UseCase on clicked on object type item`() {
fun `should invoke CreateBlockLinkWithObject UseCase on clicked on object type item`() {
// SETUP
val doc = MockTypicalDocumentFactory.page(root)
val a = MockTypicalDocumentFactory.a
@ -49,7 +49,7 @@ class EditorSlashWidgetObjectTypeTest : EditorPresentationTestSetup() {
stubInterceptEvents()
stubUpdateText()
stubSearchObjects(listOf(type1, type2, type3))
stubCreateObject(root, a.id)
stubCreateBlockLinkWithObject(root, a.id)
stubOpenDocument(doc)
val vm = buildViewModel()
@ -78,14 +78,13 @@ class EditorSlashWidgetObjectTypeTest : EditorPresentationTestSetup() {
)
)
val params = CreateObject.Params(
val params = CreateBlockLinkWithObject.Params(
context = root,
target = a.id,
position = Position.BOTTOM,
type = type2.id,
layout = null
type = type2.id
)
verifyBlocking(createObject, times(1)) { invoke(params) }
verifyBlocking(createBlockLinkWithObject, times(1)) { execute(params) }
}
}

View file

@ -4,18 +4,15 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.core_models.Position
import com.anytypeio.anytype.domain.base.Either
import com.anytypeio.anytype.domain.base.Resultat
import com.anytypeio.anytype.domain.block.interactor.CreateBlock
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
import com.anytypeio.anytype.domain.page.CreateDocument
import com.anytypeio.anytype.presentation.util.CoroutinesTestRule
import com.anytypeio.anytype.test_utils.MockDataFactory
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.stub
import org.mockito.kotlin.times
@ -153,97 +150,6 @@ class EditorTitleAddBlockTest : EditorPresentationTestSetup() {
verifyBlocking(createBlock, times(1)) { execute(params) }
}
@Test
fun `should create a new document after title if document has only title block`() {
// SETUP
val page = Block(
id = root,
fields = Block.Fields(emptyMap()),
content = Block.Content.Smart(),
children = listOf(header.id)
)
val params = CreateDocument.Params(
context = root,
target = title.id,
position = Position.BOTTOM
)
val document = listOf(page, header, title)
stubOpenDocument(document = document)
stubInterceptEvents(InterceptEvents.Params(context = root))
stubCreateDocument(params)
val vm = buildViewModel()
// TESTING
vm.apply {
onStart(root)
onBlockFocusChanged(
id = title.id,
hasFocus = true
)
onAddNewPageClicked()
}
verifyBlocking(createDocument, times(1)) { invoke(params) }
}
@Test
fun `should create a new document below document title`() {
// SETUP
val block = Block(
id = MockDataFactory.randomUuid(),
fields = Block.Fields(emptyMap()),
content = Block.Content.Text(
text = MockDataFactory.randomString(),
marks = emptyList(),
style = Block.Content.Text.Style.values().random()
),
children = emptyList()
)
val page = Block(
id = root,
fields = Block.Fields(emptyMap()),
content = Block.Content.Smart(),
children = listOf(header.id, block.id)
)
val params = CreateDocument.Params(
context = root,
target = title.id,
position = Position.BOTTOM
)
val document = listOf(page, header, title)
stubOpenDocument(document = document)
stubInterceptEvents(InterceptEvents.Params(context = root))
stubCreateDocument(params)
val vm = buildViewModel()
// TESTING
vm.apply {
onStart(root)
onBlockFocusChanged(
id = title.id,
hasFocus = true
)
onAddNewPageClicked()
}
verifyBlocking(createDocument, times(1)) { invoke(params) }
}
@Test
fun `should create a new file block below title if document has only title block`() {
@ -552,21 +458,4 @@ class EditorTitleAddBlockTest : EditorPresentationTestSetup() {
)
}
}
private fun stubCreateDocument(
params: CreateDocument.Params
) {
createDocument.stub {
onBlocking { invoke(params) } doReturn Either.Right(
CreateDocument.Result(
id = MockDataFactory.randomUuid(),
payload = Payload(
context = root,
events = emptyList()
),
target = MockDataFactory.randomUuid()
)
)
}
}
}

View file

@ -66,6 +66,6 @@ class ObjectSetInitializationTest : ObjectSetViewModelTestSetup() {
vm.onStart(ctx = ctx)
vm.onCreateNewDataViewObject()
verifyNoInteractions(createNewObject)
verifyNoInteractions(createObject)
}
}

View file

@ -8,6 +8,7 @@ import com.anytypeio.anytype.core_models.DVViewer
import com.anytypeio.anytype.core_models.DVViewerRelation
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.core_models.Relation
import com.anytypeio.anytype.core_models.RelationLink
import com.anytypeio.anytype.core_models.Relations
@ -17,6 +18,7 @@ import com.anytypeio.anytype.core_models.StubRelationObject
import com.anytypeio.anytype.core_models.StubTitle
import com.anytypeio.anytype.core_models.ext.content
import com.anytypeio.anytype.domain.base.Resultat
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.presentation.navigation.AppNavigation
import com.anytypeio.anytype.presentation.objects.SupportedLayouts
import com.anytypeio.anytype.presentation.relations.ObjectSetConfig
@ -588,8 +590,16 @@ class ObjectSetNavigationTest : ObjectSetViewModelTestSetup() {
}
private fun givenDelegateId(id: String) {
createNewObject.stub {
onBlocking { execute(Unit) } doReturn Resultat.success(id)
createObject.stub {
onBlocking { execute(CreateObject.Param(null)) } doReturn Resultat.success(
CreateObject.Result(
objectId = id,
event = Payload(
context = id,
events = listOf()
)
)
)
}
}
}

View file

@ -35,7 +35,7 @@ import com.anytypeio.anytype.domain.objects.DefaultStoreOfRelations
import com.anytypeio.anytype.domain.objects.ObjectStore
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.domain.page.CloseBlock
import com.anytypeio.anytype.domain.page.CreateNewObject
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.CancelSearchSubscription
import com.anytypeio.anytype.domain.search.DataViewSubscriptionContainer
import com.anytypeio.anytype.domain.search.SubscriptionEventChannel
@ -59,7 +59,6 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.StandardTestDispatcher
import org.mockito.Mock
import org.mockito.kotlin.any
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.stub
@ -104,7 +103,7 @@ open class ObjectSetViewModelTestSetup {
lateinit var getTemplates: GetTemplates
@Mock
lateinit var createNewObject: CreateNewObject
lateinit var createObject: CreateObject
@Mock
lateinit var setDataViewSource: SetDataViewSource
@ -168,7 +167,7 @@ open class ObjectSetViewModelTestSetup {
analytics = analytics,
downloadUnsplashImage = downloadUnsplashImage,
setDocCoverImage = setDocCoverImage,
createNewObject = createNewObject,
createObject = createObject,
setDataViewSource = setDataViewSource,
setObjectDetails = setObjectDetails,
paginator = paginator,

View file

@ -16,7 +16,7 @@ import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.launch.GetDefaultEditorType
import com.anytypeio.anytype.domain.launch.SetDefaultEditorType
import com.anytypeio.anytype.domain.misc.AppActionManager
import com.anytypeio.anytype.domain.page.CreatePage
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.ObjectTypesSubscriptionManager
import com.anytypeio.anytype.domain.search.RelationsSubscriptionManager
import com.anytypeio.anytype.presentation.util.CoroutinesTestRule
@ -71,7 +71,7 @@ class SplashViewModelTest {
private lateinit var setDefaultEditorType: SetDefaultEditorType
@Mock
lateinit var createPage: CreatePage
lateinit var createObject: CreateObject
@Mock
lateinit var appActionManager: AppActionManager
@ -105,7 +105,7 @@ class SplashViewModelTest {
getLastOpenedObject = getLastOpenedObject,
setDefaultEditorType = setDefaultEditorType,
getDefaultEditorType = getDefaultEditorType,
createPage = createPage,
createObject = createObject,
appActionManager = appActionManager,
relationsSubscriptionManager = relationsSubscriptionManager,
objectTypesSubscriptionManager = objectTypesSubscriptionManager