mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 13:57:10 +09:00
Feature | Setting cover from Unsplash (without loading state) (#2141)
This commit is contained in:
parent
b24596a26e
commit
1e130241ff
53 changed files with 1141 additions and 52 deletions
|
@ -36,7 +36,9 @@ import com.anytypeio.anytype.domain.page.bookmark.SetupBookmark
|
|||
import com.anytypeio.anytype.domain.sets.FindObjectSetForType
|
||||
import com.anytypeio.anytype.domain.status.InterceptThreadStatus
|
||||
import com.anytypeio.anytype.domain.status.ThreadStatusChannel
|
||||
import com.anytypeio.anytype.domain.unsplash.DownloadUnsplashImage
|
||||
import com.anytypeio.anytype.mocking.MockDataFactory
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.editor.DocumentExternalEventReducer
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
import com.anytypeio.anytype.presentation.editor.EditorViewModelFactory
|
||||
|
@ -173,6 +175,8 @@ open class EditorTestSetup {
|
|||
@Mock
|
||||
lateinit var objectTypesProvider: ObjectTypesProvider
|
||||
|
||||
lateinit var downloadUnsplashImage: DownloadUnsplashImage
|
||||
|
||||
val root: String = "rootId123"
|
||||
|
||||
private val urlBuilder by lazy {
|
||||
|
@ -310,7 +314,10 @@ open class EditorTestSetup {
|
|||
getDefaultEditorType = getDefaultEditorType,
|
||||
createObjectSet = createObjectSet,
|
||||
findObjectSetForType = findObjectSetForType,
|
||||
copyFileToCacheDirectory = copyFileToCacheDirectory
|
||||
copyFileToCacheDirectory = copyFileToCacheDirectory,
|
||||
downloadUnsplashImage = downloadUnsplashImage,
|
||||
delegator = Delegator.Default(),
|
||||
setDocCoverImage = setDocCoverImage
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import androidx.test.espresso.matcher.ViewMatchers.*
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
import com.anytypeio.anytype.domain.icon.RemoveDocumentIcon
|
||||
import com.anytypeio.anytype.domain.icon.SetDocumentEmojiIcon
|
||||
|
@ -47,6 +48,9 @@ class DocumentEmojiPickerFragmentTest {
|
|||
@Mock
|
||||
lateinit var provider: EmojiProvider
|
||||
|
||||
@Mock
|
||||
lateinit var analytics: Analytics
|
||||
|
||||
@Mock
|
||||
lateinit var repo: BlockRepository
|
||||
|
||||
|
@ -67,7 +71,8 @@ class DocumentEmojiPickerFragmentTest {
|
|||
setEmojiIcon = setEmojiIcon,
|
||||
setImageIcon = setImageIcon,
|
||||
removeDocumentIcon = removeDocumentIcon,
|
||||
dispatcher = Dispatcher.Default()
|
||||
dispatcher = Dispatcher.Default(),
|
||||
analytics = analytics
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import androidx.fragment.app.testing.launchFragmentInContainer
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.domain.`object`.ObjectTypesProvider
|
||||
import com.anytypeio.anytype.domain.`object`.UpdateDetail
|
||||
|
@ -53,6 +54,9 @@ class AddRelationStatusValueTest {
|
|||
@Mock
|
||||
lateinit var dispatcher: Dispatcher<Payload>
|
||||
|
||||
@Mock
|
||||
lateinit var analytics: Analytics
|
||||
|
||||
private lateinit var addRelationOption: AddDataViewRelationOption
|
||||
private lateinit var addObjectRelationOption: AddObjectRelationOption
|
||||
private lateinit var removeTagFromDataViewRecord: RemoveTagFromDataViewRecord
|
||||
|
@ -96,6 +100,7 @@ class AddRelationStatusValueTest {
|
|||
addStatusToDataViewRecord = addStatusToDataViewRecord,
|
||||
urlBuilder = urlBuilder,
|
||||
dispatcher = dispatcher,
|
||||
analytics = analytics
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import androidx.fragment.app.testing.launchFragmentInContainer
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.domain.`object`.ObjectTypesProvider
|
||||
import com.anytypeio.anytype.domain.`object`.UpdateDetail
|
||||
|
@ -53,6 +54,9 @@ class AddRelationTagValueTest {
|
|||
@Mock
|
||||
lateinit var dispatcher: Dispatcher<Payload>
|
||||
|
||||
@Mock
|
||||
lateinit var analytics: Analytics
|
||||
|
||||
private lateinit var addRelationOption: AddDataViewRelationOption
|
||||
private lateinit var addObjectRelationOption: AddObjectRelationOption
|
||||
private lateinit var removeTagFromDataViewRecord: RemoveTagFromDataViewRecord
|
||||
|
@ -95,7 +99,8 @@ class AddRelationTagValueTest {
|
|||
addTagToDataViewRecord = addTagToDataViewRecord,
|
||||
addStatusToDataViewRecord = addStatusToDataViewRecord,
|
||||
urlBuilder = urlBuilder,
|
||||
dispatcher = dispatcher
|
||||
dispatcher = dispatcher,
|
||||
analytics = analytics
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
|
@ -65,6 +66,9 @@ class ObjectRelationListTest {
|
|||
@Mock
|
||||
lateinit var detailModificationManager: DetailModificationManager
|
||||
|
||||
@Mock
|
||||
lateinit var analytics: Analytics
|
||||
|
||||
private lateinit var objectRelationList: ObjectRelationList
|
||||
private lateinit var updateDetail: UpdateDetail
|
||||
private lateinit var addToFeaturedRelations: AddToFeaturedRelations
|
||||
|
@ -94,7 +98,8 @@ class ObjectRelationListTest {
|
|||
updateDetail = updateDetail,
|
||||
addToFeaturedRelations = addToFeaturedRelations,
|
||||
removeFromFeaturedRelations = removeFromFeaturedRelations,
|
||||
deleteRelationFromObject = deleteRelationFromObject
|
||||
deleteRelationFromObject = deleteRelationFromObject,
|
||||
analytics = analytics
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.anytypeio.anytype.domain.base.Result
|
|||
import com.anytypeio.anytype.domain.block.interactor.UpdateText
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
import com.anytypeio.anytype.domain.config.Gateway
|
||||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.*
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
|
@ -18,8 +19,12 @@ import com.anytypeio.anytype.domain.page.CloseBlock
|
|||
import com.anytypeio.anytype.domain.sets.OpenObjectSet
|
||||
import com.anytypeio.anytype.domain.status.InterceptThreadStatus
|
||||
import com.anytypeio.anytype.domain.status.ThreadStatusChannel
|
||||
import com.anytypeio.anytype.domain.unsplash.DownloadUnsplashImage
|
||||
import com.anytypeio.anytype.domain.unsplash.UnsplashRepository
|
||||
import com.anytypeio.anytype.emojifier.data.DefaultDocumentEmojiIconProvider
|
||||
import com.anytypeio.anytype.mocking.MockDataFactory
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.sets.ObjectSetRecordCache
|
||||
import com.anytypeio.anytype.presentation.sets.ObjectSetReducer
|
||||
import com.anytypeio.anytype.presentation.sets.ObjectSetSession
|
||||
|
@ -43,12 +48,17 @@ abstract class TestObjectSetSetup {
|
|||
private lateinit var closeBlock: CloseBlock
|
||||
private lateinit var setActiveViewer: SetActiveViewer
|
||||
private lateinit var interceptThreadStatus: InterceptThreadStatus
|
||||
private lateinit var setDocCoverImage: SetDocCoverImage
|
||||
private lateinit var downloadUnsplashImage: DownloadUnsplashImage
|
||||
|
||||
lateinit var urlBuilder: UrlBuilder
|
||||
|
||||
@Mock
|
||||
lateinit var repo: BlockRepository
|
||||
|
||||
@Mock
|
||||
lateinit var unsplashRepo: UnsplashRepository
|
||||
|
||||
@Mock
|
||||
lateinit var auth: AuthRepository
|
||||
|
||||
|
@ -89,6 +99,8 @@ abstract class TestObjectSetSetup {
|
|||
)
|
||||
)
|
||||
|
||||
val delegator = Delegator.Default<Action>()
|
||||
|
||||
open fun setup() {
|
||||
MockitoAnnotations.openMocks(this)
|
||||
|
||||
|
@ -102,6 +114,8 @@ abstract class TestObjectSetSetup {
|
|||
interceptThreadStatus = InterceptThreadStatus(channel = threadStatusChannel)
|
||||
closeBlock = CloseBlock(repo)
|
||||
urlBuilder = UrlBuilder(gateway)
|
||||
downloadUnsplashImage = DownloadUnsplashImage(unsplashRepo)
|
||||
setDocCoverImage = SetDocCoverImage(repo)
|
||||
|
||||
TestObjectSetFragment.testVmFactory = ObjectSetViewModelFactory(
|
||||
openObjectSet = openObjectSet,
|
||||
|
@ -119,7 +133,10 @@ abstract class TestObjectSetSetup {
|
|||
dispatcher = dispatcher,
|
||||
reducer = reducer,
|
||||
objectSetRecordCache = objectSetRecordCache,
|
||||
analytics = analytics
|
||||
analytics = analytics,
|
||||
downloadUnsplashImage = downloadUnsplashImage,
|
||||
setDocCoverImage = setDocCoverImage,
|
||||
delegator = delegator
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import androidx.test.espresso.Espresso.onView
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.domain.`object`.ObjectTypesProvider
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
|
@ -51,6 +52,9 @@ class CreateSelectedFilterTest {
|
|||
@Mock
|
||||
lateinit var objectTypesProvider: ObjectTypesProvider
|
||||
|
||||
@Mock
|
||||
lateinit var analytics: Analytics
|
||||
|
||||
lateinit var updateDataViewViewer: UpdateDataViewViewer
|
||||
lateinit var searchObjects: SearchObjects
|
||||
lateinit var urlBuilder: UrlBuilder
|
||||
|
@ -73,7 +77,8 @@ class CreateSelectedFilterTest {
|
|||
urlBuilder = urlBuilder,
|
||||
searchObjects = searchObjects,
|
||||
objectSetState = state,
|
||||
objectTypesProvider = objectTypesProvider
|
||||
objectTypesProvider = objectTypesProvider,
|
||||
analytics = analytics
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import androidx.test.espresso.Espresso.onView
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
import com.anytypeio.anytype.domain.config.Gateway
|
||||
|
@ -50,6 +51,9 @@ class FilterListTest {
|
|||
@Mock
|
||||
lateinit var gateway: Gateway
|
||||
|
||||
@Mock
|
||||
lateinit var analytics: Analytics
|
||||
|
||||
lateinit var updateDataViewViewer: UpdateDataViewViewer
|
||||
lateinit var searchObjects: SearchObjects
|
||||
lateinit var urlBuilder: UrlBuilder
|
||||
|
@ -70,7 +74,8 @@ class FilterListTest {
|
|||
updateDataViewViewer = updateDataViewViewer,
|
||||
dispatcher = dispatcher,
|
||||
urlBuilder = urlBuilder,
|
||||
state = state
|
||||
state = state,
|
||||
analytics = analytics
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import androidx.test.espresso.matcher.ViewMatchers.*
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.domain.`object`.ObjectTypesProvider
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
|
@ -57,6 +58,9 @@ class ModifyInputValueFilterTest {
|
|||
@Mock
|
||||
lateinit var gateway: Gateway
|
||||
|
||||
@Mock
|
||||
lateinit var analytics: Analytics
|
||||
|
||||
lateinit var updateDataViewViewer: UpdateDataViewViewer
|
||||
lateinit var searchObjects: SearchObjects
|
||||
lateinit var urlBuilder: UrlBuilder
|
||||
|
@ -79,7 +83,8 @@ class ModifyInputValueFilterTest {
|
|||
dispatcher = dispatcher,
|
||||
searchObjects = searchObjects,
|
||||
urlBuilder = urlBuilder,
|
||||
objectTypesProvider = objectTypesProvider
|
||||
objectTypesProvider = objectTypesProvider,
|
||||
analytics = analytics
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import androidx.test.espresso.matcher.ViewMatchers.*
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.domain.`object`.ObjectTypesProvider
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
|
@ -56,6 +57,9 @@ class ModifyStatusFilterTest {
|
|||
@Mock
|
||||
lateinit var objectTypesProvider: ObjectTypesProvider
|
||||
|
||||
@Mock
|
||||
lateinit var analytics: Analytics
|
||||
|
||||
lateinit var updateDataViewViewer: UpdateDataViewViewer
|
||||
lateinit var searchObjects: SearchObjects
|
||||
lateinit var urlBuilder: UrlBuilder
|
||||
|
@ -78,7 +82,8 @@ class ModifyStatusFilterTest {
|
|||
dispatcher = dispatcher,
|
||||
searchObjects = searchObjects,
|
||||
urlBuilder = urlBuilder,
|
||||
objectTypesProvider = objectTypesProvider
|
||||
objectTypesProvider = objectTypesProvider,
|
||||
analytics = analytics
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import androidx.test.espresso.matcher.ViewMatchers.*
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.domain.`object`.ObjectTypesProvider
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
|
@ -54,6 +55,9 @@ class ModifyTagFilterTest {
|
|||
@Mock
|
||||
lateinit var objectTypesProvider: ObjectTypesProvider
|
||||
|
||||
@Mock
|
||||
lateinit var analytics: Analytics
|
||||
|
||||
lateinit var updateDataViewViewer: UpdateDataViewViewer
|
||||
lateinit var searchObjects: SearchObjects
|
||||
lateinit var urlBuilder: UrlBuilder
|
||||
|
@ -76,7 +80,8 @@ class ModifyTagFilterTest {
|
|||
dispatcher = dispatcher,
|
||||
searchObjects = searchObjects,
|
||||
urlBuilder = urlBuilder,
|
||||
objectTypesProvider = objectTypesProvider
|
||||
objectTypesProvider = objectTypesProvider,
|
||||
analytics = analytics
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.DVSort
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
|
@ -47,6 +48,9 @@ class ViewerObjectSortTest {
|
|||
@Mock
|
||||
lateinit var repo: BlockRepository
|
||||
|
||||
@Mock
|
||||
lateinit var analytics: Analytics
|
||||
|
||||
private lateinit var updateDataViewViewer: UpdateDataViewViewer
|
||||
|
||||
private val root = MockDataFactory.randomUuid()
|
||||
|
@ -62,7 +66,8 @@ class ViewerObjectSortTest {
|
|||
state = state,
|
||||
session = session,
|
||||
updateDataViewViewer = updateDataViewViewer,
|
||||
dispatcher = dispatcher
|
||||
dispatcher = dispatcher,
|
||||
analytics = analytics
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.anytypeio.anytype.di.common
|
|||
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.di.feature.*
|
||||
import com.anytypeio.anytype.di.feature.cover.UnsplashModule
|
||||
import com.anytypeio.anytype.di.feature.relations.*
|
||||
import com.anytypeio.anytype.di.feature.sets.CreateFilterModule
|
||||
import com.anytypeio.anytype.di.feature.sets.ModifyFilterModule
|
||||
|
@ -522,6 +523,22 @@ class ComponentManager(private val main: MainComponent) {
|
|||
.build()
|
||||
}
|
||||
|
||||
val objectUnsplashComponent = DependentComponentMap { ctx ->
|
||||
editorComponent
|
||||
.get(ctx)
|
||||
.objectUnsplashComponent()
|
||||
.module(UnsplashModule)
|
||||
.build()
|
||||
}
|
||||
|
||||
val objectSetUnsplashComponent = DependentComponentMap { ctx ->
|
||||
objectSetComponent
|
||||
.get(ctx)
|
||||
.objectUnsplashComponent()
|
||||
.module(UnsplashModule)
|
||||
.build()
|
||||
}
|
||||
|
||||
val objectSetCoverComponent = DependentComponentMap { ctx ->
|
||||
objectSetComponent
|
||||
.get(ctx)
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.anytypeio.anytype.core_models.Id
|
|||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
|
||||
import com.anytypeio.anytype.di.feature.cover.UnsplashSubComponent
|
||||
import com.anytypeio.anytype.di.feature.relations.RelationAddToObjectSubComponent
|
||||
import com.anytypeio.anytype.di.feature.relations.RelationCreateFromScratchForObjectBlockSubComponent
|
||||
import com.anytypeio.anytype.di.feature.relations.RelationCreateFromScratchForObjectSubComponent
|
||||
|
@ -22,6 +23,7 @@ import com.anytypeio.anytype.domain.clipboard.Clipboard
|
|||
import com.anytypeio.anytype.domain.clipboard.Copy
|
||||
import com.anytypeio.anytype.domain.clipboard.Paste
|
||||
import com.anytypeio.anytype.domain.config.UserSettingsRepository
|
||||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.GetCompatibleObjectTypes
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.SearchObjects
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.SetRelationKey
|
||||
|
@ -40,6 +42,10 @@ import com.anytypeio.anytype.domain.relations.AddFileToObject
|
|||
import com.anytypeio.anytype.domain.sets.FindObjectSetForType
|
||||
import com.anytypeio.anytype.domain.status.InterceptThreadStatus
|
||||
import com.anytypeio.anytype.domain.status.ThreadStatusChannel
|
||||
import com.anytypeio.anytype.domain.unsplash.DownloadUnsplashImage
|
||||
import com.anytypeio.anytype.domain.unsplash.UnsplashRepository
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.editor.DocumentExternalEventReducer
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
import com.anytypeio.anytype.presentation.editor.EditorViewModelFactory
|
||||
|
@ -89,6 +95,7 @@ interface EditorSubComponent {
|
|||
fun editRelationDateComponent(): RelationDataValueSubComponent.Builder
|
||||
|
||||
fun objectCoverComponent() : SelectCoverObjectSubComponent.Builder
|
||||
fun objectUnsplashComponent() : UnsplashSubComponent.Builder
|
||||
fun objectMenuComponent() : ObjectMenuComponent.Builder
|
||||
|
||||
fun objectLayoutComponent() : ObjectLayoutSubComponent.Builder
|
||||
|
@ -142,6 +149,7 @@ object EditorSessionModule {
|
|||
orchestrator: Orchestrator,
|
||||
analytics: Analytics,
|
||||
dispatcher: Dispatcher<Payload>,
|
||||
delegator: Delegator<Action>,
|
||||
detailModificationManager: DetailModificationManager,
|
||||
updateDetail: UpdateDetail,
|
||||
getCompatibleObjectTypes: GetCompatibleObjectTypes,
|
||||
|
@ -149,7 +157,9 @@ object EditorSessionModule {
|
|||
searchObjects: SearchObjects,
|
||||
getDefaultEditorType: GetDefaultEditorType,
|
||||
findObjectSetForType: FindObjectSetForType,
|
||||
copyFileToCacheDirectory: CopyFileToCacheDirectory
|
||||
copyFileToCacheDirectory: CopyFileToCacheDirectory,
|
||||
downloadUnsplashImage: DownloadUnsplashImage,
|
||||
setDocCoverImage: SetDocCoverImage
|
||||
): EditorViewModelFactory = EditorViewModelFactory(
|
||||
openPage = openPage,
|
||||
closeObject = closePage,
|
||||
|
@ -168,6 +178,7 @@ object EditorSessionModule {
|
|||
orchestrator = orchestrator,
|
||||
analytics = analytics,
|
||||
dispatcher = dispatcher,
|
||||
delegator = delegator,
|
||||
detailModificationManager = detailModificationManager,
|
||||
updateDetail = updateDetail,
|
||||
getCompatibleObjectTypes = getCompatibleObjectTypes,
|
||||
|
@ -176,7 +187,9 @@ object EditorSessionModule {
|
|||
getDefaultEditorType = getDefaultEditorType,
|
||||
findObjectSetForType = findObjectSetForType,
|
||||
createObjectSet = createObjectSet,
|
||||
copyFileToCacheDirectory = copyFileToCacheDirectory
|
||||
copyFileToCacheDirectory = copyFileToCacheDirectory,
|
||||
downloadUnsplashImage = downloadUnsplashImage,
|
||||
setDocCoverImage = setDocCoverImage
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
@ -689,6 +702,11 @@ object EditorUseCaseModule {
|
|||
@PerScreen
|
||||
fun providePayloadDispatcher() : Dispatcher<Payload> = Dispatcher.Default()
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerScreen
|
||||
fun provideDelegator() : Delegator<Action> = Delegator.Default()
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerScreen
|
||||
|
@ -771,4 +789,18 @@ object EditorUseCaseModule {
|
|||
fun provideCopyFileToCache(
|
||||
context: Context
|
||||
): CopyFileToCacheDirectory = DefaultCopyFileToCacheDirectory(context)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerScreen
|
||||
fun provideDownload(repo: UnsplashRepository): DownloadUnsplashImage = DownloadUnsplashImage(
|
||||
repo = repo
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerScreen
|
||||
fun provideSetDocCoverImageUseCase(
|
||||
repo: BlockRepository
|
||||
): SetDocCoverImage = SetDocCoverImage(repo)
|
||||
}
|
|
@ -6,6 +6,7 @@ import com.anytypeio.anytype.core_models.Id
|
|||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
|
||||
import com.anytypeio.anytype.di.feature.cover.UnsplashSubComponent
|
||||
import com.anytypeio.anytype.di.feature.relations.RelationAddToDataViewSubComponent
|
||||
import com.anytypeio.anytype.di.feature.relations.RelationCreateFromScratchForDataViewSubComponent
|
||||
import com.anytypeio.anytype.di.feature.sets.CreateFilterSubComponent
|
||||
|
@ -17,6 +18,7 @@ import com.anytypeio.anytype.domain.`object`.UpdateDetail
|
|||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
import com.anytypeio.anytype.domain.block.interactor.UpdateText
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.*
|
||||
import com.anytypeio.anytype.domain.event.interactor.EventChannel
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
|
@ -28,6 +30,10 @@ import com.anytypeio.anytype.domain.relations.DeleteRelationFromDataView
|
|||
import com.anytypeio.anytype.domain.sets.OpenObjectSet
|
||||
import com.anytypeio.anytype.domain.status.InterceptThreadStatus
|
||||
import com.anytypeio.anytype.domain.status.ThreadStatusChannel
|
||||
import com.anytypeio.anytype.domain.unsplash.DownloadUnsplashImage
|
||||
import com.anytypeio.anytype.domain.unsplash.UnsplashRepository
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.relations.providers.*
|
||||
import com.anytypeio.anytype.presentation.sets.*
|
||||
import com.anytypeio.anytype.presentation.util.Dispatcher
|
||||
|
@ -76,6 +82,7 @@ interface ObjectSetSubComponent {
|
|||
fun objectSetMenuComponent() : ObjectSetMenuComponent.Builder
|
||||
fun objectSetIconPickerComponent() : ObjectSetIconPickerComponent.Builder
|
||||
fun objectSetCoverComponent() : SelectCoverObjectSetSubComponent.Builder
|
||||
fun objectUnsplashComponent() : UnsplashSubComponent.Builder
|
||||
}
|
||||
|
||||
@Module
|
||||
|
@ -97,10 +104,13 @@ object ObjectSetModule {
|
|||
createDataViewRecord: CreateDataViewRecord,
|
||||
reducer: ObjectSetReducer,
|
||||
dispatcher: Dispatcher<Payload>,
|
||||
delegator: Delegator<Action>,
|
||||
objectSetRecordCache: ObjectSetRecordCache,
|
||||
urlBuilder: UrlBuilder,
|
||||
session: ObjectSetSession,
|
||||
analytics: Analytics
|
||||
analytics: Analytics,
|
||||
downloadUnsplashImage: DownloadUnsplashImage,
|
||||
setDocCoverImage: SetDocCoverImage
|
||||
): ObjectSetViewModelFactory = ObjectSetViewModelFactory(
|
||||
openObjectSet = openObjectSet,
|
||||
closeBlock = closeBlock,
|
||||
|
@ -114,10 +124,13 @@ object ObjectSetModule {
|
|||
interceptThreadStatus = interceptThreadStatus,
|
||||
reducer = reducer,
|
||||
dispatcher = dispatcher,
|
||||
delegator = delegator,
|
||||
objectSetRecordCache = objectSetRecordCache,
|
||||
urlBuilder = urlBuilder,
|
||||
session = session,
|
||||
analytics = analytics
|
||||
analytics = analytics,
|
||||
downloadUnsplashImage = downloadUnsplashImage,
|
||||
setDocCoverImage = setDocCoverImage
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
@ -218,6 +231,11 @@ object ObjectSetModule {
|
|||
@PerScreen
|
||||
fun provideDispatcher(): Dispatcher<Payload> = Dispatcher.Default()
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerScreen
|
||||
fun provideDelegator() : Delegator<Action> = Delegator.Default()
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerScreen
|
||||
|
@ -292,4 +310,18 @@ object ObjectSetModule {
|
|||
fun provideDeleteRelationFromDataViewUseCase(
|
||||
repo: BlockRepository
|
||||
): DeleteRelationFromDataView = DeleteRelationFromDataView(repo = repo)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerScreen
|
||||
fun provideSetDocCoverImageUseCase(
|
||||
repo: BlockRepository
|
||||
): SetDocCoverImage = SetDocCoverImage(repo)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerScreen
|
||||
fun provideDownload(repo: UnsplashRepository): DownloadUnsplashImage = DownloadUnsplashImage(
|
||||
repo = repo
|
||||
)
|
||||
}
|
|
@ -45,13 +45,6 @@ object SelectCoverObjectModule {
|
|||
repo: BlockRepository
|
||||
): SetDocCoverGradient = SetDocCoverGradient(repo)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerModal
|
||||
fun provideSetDocCoverImageUseCase(
|
||||
repo: BlockRepository
|
||||
): SetDocCoverImage = SetDocCoverImage(repo)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerModal
|
||||
|
@ -118,13 +111,6 @@ object SelectCoverObjectSetModule {
|
|||
repo: BlockRepository
|
||||
): SetDocCoverGradient = SetDocCoverGradient(repo)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerModal
|
||||
fun provideSetDocCoverImageUseCase(
|
||||
repo: BlockRepository
|
||||
): SetDocCoverImage = SetDocCoverImage(repo)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerModal
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package com.anytypeio.anytype.di.feature.cover
|
||||
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerDialog
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.unsplash.SearchUnsplashImage
|
||||
import com.anytypeio.anytype.domain.unsplash.UnsplashRepository
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.editor.cover.UnsplashViewModel
|
||||
import com.anytypeio.anytype.ui.editor.cover.UnsplashBaseFragment
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.Subcomponent
|
||||
|
||||
@Subcomponent(modules = [UnsplashModule::class])
|
||||
@PerDialog
|
||||
interface UnsplashSubComponent {
|
||||
|
||||
@Subcomponent.Builder
|
||||
interface Builder {
|
||||
fun module(module: UnsplashModule): Builder
|
||||
fun build(): UnsplashSubComponent
|
||||
}
|
||||
|
||||
fun inject(fragment: UnsplashBaseFragment)
|
||||
}
|
||||
|
||||
@Module
|
||||
object UnsplashModule {
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerDialog
|
||||
fun provideViewModelFactory(
|
||||
search: SearchUnsplashImage,
|
||||
delegator: Delegator<Action>
|
||||
): UnsplashViewModel.Factory {
|
||||
return UnsplashViewModel.Factory(
|
||||
search = search,
|
||||
delegator = delegator
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerDialog
|
||||
fun provideSearch(repo: UnsplashRepository): SearchUnsplashImage = SearchUnsplashImage(
|
||||
repo = repo
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerDialog
|
||||
fun provideSetDocCoverImageUseCase(
|
||||
repo: BlockRepository
|
||||
): SetDocCoverImage = SetDocCoverImage(repo)
|
||||
}
|
|
@ -14,6 +14,8 @@ import com.anytypeio.anytype.data.auth.repo.block.BlockDataStoreFactory
|
|||
import com.anytypeio.anytype.data.auth.repo.block.BlockRemote
|
||||
import com.anytypeio.anytype.data.auth.repo.block.BlockRemoteDataStore
|
||||
import com.anytypeio.anytype.data.auth.repo.config.Configurator
|
||||
import com.anytypeio.anytype.data.auth.repo.unsplash.UnsplashDataRepository
|
||||
import com.anytypeio.anytype.data.auth.repo.unsplash.UnsplashRemote
|
||||
import com.anytypeio.anytype.data.auth.types.DefaultObjectTypesProvider
|
||||
import com.anytypeio.anytype.device.DefaultPathProvider
|
||||
import com.anytypeio.anytype.domain.`object`.ObjectTypesProvider
|
||||
|
@ -26,7 +28,9 @@ import com.anytypeio.anytype.domain.device.PathProvider
|
|||
import com.anytypeio.anytype.domain.misc.AppActionManager
|
||||
import com.anytypeio.anytype.domain.objects.DefaultObjectStore
|
||||
import com.anytypeio.anytype.domain.objects.ObjectStore
|
||||
import com.anytypeio.anytype.domain.unsplash.UnsplashRepository
|
||||
import com.anytypeio.anytype.middleware.EventProxy
|
||||
import com.anytypeio.anytype.middleware.UnsplashMiddleware
|
||||
import com.anytypeio.anytype.middleware.auth.AuthMiddleware
|
||||
import com.anytypeio.anytype.middleware.block.BlockMiddleware
|
||||
import com.anytypeio.anytype.middleware.interactor.Middleware
|
||||
|
@ -278,4 +282,26 @@ object DataModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
fun provideObjectStore() : ObjectStore = DefaultObjectStore()
|
||||
|
||||
//region Unsplash
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideUnsplashRepo(
|
||||
remote: UnsplashRemote
|
||||
) : UnsplashRepository = UnsplashDataRepository(
|
||||
remote = remote
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideUnsplashRemote(
|
||||
service: MiddlewareService
|
||||
) : UnsplashRemote = UnsplashMiddleware(
|
||||
service = service
|
||||
)
|
||||
|
||||
//endregion
|
||||
}
|
|
@ -71,11 +71,22 @@ abstract class SelectCoverGalleryFragment : BaseBottomSheetFragment<FragmentDocC
|
|||
.onEach { vm.onRemoveCover(ctx) }
|
||||
.launchIn(lifecycleScope)
|
||||
|
||||
binding.btnUnsplash.clicks()
|
||||
.onEach {
|
||||
findNavController().navigate(
|
||||
R.id.objectCoverUnsplashScreen,
|
||||
bundleOf(
|
||||
UnsplashBaseFragment.CTX_KEY to ctx
|
||||
)
|
||||
)
|
||||
}
|
||||
.launchIn(lifecycleScope)
|
||||
|
||||
binding.btnUpload.clicks()
|
||||
.onEach { proceedWithImagePick() }
|
||||
.launchIn(lifecycleScope)
|
||||
|
||||
val spacing = requireContext().dimen(R.dimen.cover_gallery_item_spacing).toInt() / 2
|
||||
val spacing = requireContext().dimen(R.dimen.cover_gallery_item_spacing).toInt()
|
||||
|
||||
binding.docCoverGalleryRecycler.apply {
|
||||
adapter = docCoverGalleryAdapter
|
||||
|
@ -113,6 +124,7 @@ abstract class SelectCoverGalleryFragment : BaseBottomSheetFragment<FragmentDocC
|
|||
jobs += subscribe(vm.toasts) { toast(it) }
|
||||
}
|
||||
super.onStart()
|
||||
expand()
|
||||
}
|
||||
|
||||
private fun proceedWithImagePick() {
|
||||
|
@ -145,6 +157,8 @@ abstract class SelectCoverGalleryFragment : BaseBottomSheetFragment<FragmentDocC
|
|||
inflater, container, false
|
||||
)
|
||||
|
||||
abstract fun onUnsplashClicked()
|
||||
|
||||
companion object {
|
||||
private const val SELECT_IMAGE_CODE = 1
|
||||
private const val REQUEST_PERMISSION_CODE = 2
|
||||
|
@ -175,6 +189,15 @@ class SelectCoverObjectFragment : SelectCoverGalleryFragment() {
|
|||
lateinit var factory: SelectCoverObjectViewModel.Factory
|
||||
override val vm by viewModels<SelectCoverObjectViewModel> { factory }
|
||||
|
||||
override fun onUnsplashClicked() {
|
||||
findNavController().navigate(
|
||||
R.id.objectCoverUnsplashScreen,
|
||||
bundleOf(
|
||||
UnsplashBaseFragment.CTX_KEY to ctx
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun injectDependencies() {
|
||||
componentManager().objectCoverComponent.get(ctx).inject(this)
|
||||
}
|
||||
|
@ -208,6 +231,15 @@ class SelectCoverObjectSetFragment : SelectCoverGalleryFragment() {
|
|||
componentManager().objectSetCoverComponent.release(ctx)
|
||||
}
|
||||
|
||||
override fun onUnsplashClicked() {
|
||||
findNavController().navigate(
|
||||
R.id.objectCoverUnsplashScreen,
|
||||
bundleOf(
|
||||
UnsplashBaseFragment.CTX_KEY to ctx
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun new(ctx: Id) = SelectCoverObjectSetFragment().apply {
|
||||
arguments = bundleOf(CTX_KEY to ctx)
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
package com.anytypeio.anytype.ui.editor.cover
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.core_ui.features.cover.UnsplashImageAdapter
|
||||
import com.anytypeio.anytype.core_ui.features.editor.modal.DocCoverGalleryAdapter
|
||||
import com.anytypeio.anytype.core_utils.ext.arg
|
||||
import com.anytypeio.anytype.core_utils.ext.dimen
|
||||
import com.anytypeio.anytype.core_utils.ext.invisible
|
||||
import com.anytypeio.anytype.core_utils.ext.visible
|
||||
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
|
||||
import com.anytypeio.anytype.databinding.FragmentUnsplashBinding
|
||||
import com.anytypeio.anytype.di.common.componentManager
|
||||
import com.anytypeio.anytype.presentation.editor.cover.UnsplashViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class UnsplashBaseFragment : BaseBottomSheetFragment<FragmentUnsplashBinding>() {
|
||||
|
||||
val ctx get() = arg<String>(CTX_KEY)
|
||||
|
||||
@Inject
|
||||
lateinit var factory: UnsplashViewModel.Factory
|
||||
|
||||
private val vm by viewModels<UnsplashViewModel> { factory }
|
||||
|
||||
private val unsplashImageAdapter by lazy {
|
||||
UnsplashImageAdapter(
|
||||
onImageClicked = { img ->
|
||||
vm.onImageSelected(ctx = ctx, img = img)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val spacing = requireContext().dimen(R.dimen.cover_gallery_item_spacing).toInt()
|
||||
binding.unsplashRecycler.apply {
|
||||
adapter = unsplashImageAdapter
|
||||
layoutManager = GridLayoutManager(context, 2)
|
||||
addItemDecoration(
|
||||
object : RecyclerView.ItemDecoration() {
|
||||
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
|
||||
val position = parent.getChildAdapterPosition(view)
|
||||
val holder = parent.findViewHolderForLayoutPosition(position)
|
||||
if (holder !is DocCoverGalleryAdapter.ViewHolder.Header) {
|
||||
outRect.left = spacing
|
||||
outRect.right = spacing
|
||||
outRect.top = spacing * 2
|
||||
outRect.bottom = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
binding.searchToolbar.binding.filterInputField.doAfterTextChanged {
|
||||
vm.onQueryChanged(it.toString())
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
launch {
|
||||
vm.isCompleted.collect { isCompleted ->
|
||||
if (isCompleted) onCompleted()
|
||||
}
|
||||
}
|
||||
launch {
|
||||
vm.images.collect { unsplashImageAdapter.submitList(it) }
|
||||
}
|
||||
launch {
|
||||
vm.isLoading.collect { isLoading ->
|
||||
if (isLoading)
|
||||
binding.searchToolbar.binding.progressBar.visible()
|
||||
else
|
||||
binding.searchToolbar.binding.progressBar.invisible()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun onCompleted()
|
||||
|
||||
override fun inflateBinding(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?
|
||||
): FragmentUnsplashBinding = FragmentUnsplashBinding.inflate(
|
||||
inflater, container, false
|
||||
)
|
||||
|
||||
companion object {
|
||||
const val CTX_KEY = "arg.object.cover.unsplash.ctx"
|
||||
}
|
||||
}
|
||||
|
||||
class ObjectUnsplashFragment: UnsplashBaseFragment() {
|
||||
override fun injectDependencies() {
|
||||
componentManager().objectUnsplashComponent.get(ctx).inject(this)
|
||||
}
|
||||
|
||||
override fun releaseDependencies() {
|
||||
componentManager().objectUnsplashComponent.release(ctx)
|
||||
}
|
||||
|
||||
override fun onCompleted() {
|
||||
findNavController().popBackStack(
|
||||
R.id.pageScreen,
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class ObjectSetUnsplashFragment : UnsplashBaseFragment() {
|
||||
|
||||
override fun onCompleted() {
|
||||
findNavController().popBackStack(
|
||||
R.id.objectSetScreen,
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
override fun injectDependencies() {
|
||||
componentManager().objectSetUnsplashComponent.get(ctx).inject(this)
|
||||
}
|
||||
|
||||
override fun releaseDependencies() {
|
||||
componentManager().objectSetUnsplashComponent.release(ctx)
|
||||
}
|
||||
}
|
|
@ -46,11 +46,11 @@
|
|||
android:id="@+id/docCoverGalleryRecycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingStart="@dimen/dp_8"
|
||||
android:paddingEnd="@dimen/dp_8"
|
||||
android:layout_weight="1"
|
||||
android:clipToPadding="false"
|
||||
android:minHeight="300dp"
|
||||
android:paddingStart="@dimen/dp_8"
|
||||
android:paddingEnd="@dimen/dp_8"
|
||||
android:paddingBottom="@dimen/dp_16" />
|
||||
|
||||
<LinearLayout
|
||||
|
@ -60,23 +60,16 @@
|
|||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnGallery"
|
||||
android:id="@+id/btnUnsplash"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="17sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
android:gravity="center"
|
||||
android:text=""
|
||||
android:textColor="#ACA996"
|
||||
android:text="@string/unsplash"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:textColor="@color/glyph_active"
|
||||
android:textSize="17sp" />
|
||||
|
||||
<TextView
|
||||
|
@ -85,9 +78,11 @@
|
|||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center"
|
||||
android:text="@string/btn_upload"
|
||||
android:textColor="#ACA996"
|
||||
android:textColor="@color/glyph_active"
|
||||
android:textSize="17sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
57
app/src/main/res/layout/fragment_unsplash.xml
Normal file
57
app/src/main/res/layout/fragment_unsplash.xml
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".ui.editor.cover.SelectCoverGalleryFragment">
|
||||
|
||||
<View
|
||||
android:id="@+id/dragger"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="4dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="6dp"
|
||||
android:background="@drawable/page_icon_picker_dragger_background" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/headerToolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/default_toolbar_height"
|
||||
android:layout_marginTop="@dimen/dp_6">
|
||||
|
||||
<TextView
|
||||
style="@style/CoverModalTitleStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="@string/unsplash" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/default_toolbar_height">
|
||||
|
||||
<com.anytypeio.anytype.core_ui.widgets.DefaultSearchToolbar
|
||||
android:id="@+id/searchToolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/default_search_toolbar_clip_height"
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:layout_gravity="center_vertical"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/unsplashRecycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:clipToPadding="false"
|
||||
android:paddingStart="@dimen/dp_8"
|
||||
android:paddingEnd="@dimen/dp_8"
|
||||
android:paddingBottom="@dimen/dp_16" />
|
||||
|
||||
</LinearLayout>
|
|
@ -55,6 +55,10 @@
|
|||
android:id="@+id/objectCoverScreen"
|
||||
android:name="com.anytypeio.anytype.ui.editor.cover.SelectCoverObjectFragment"
|
||||
android:label="Object-Cover-Screen"/>
|
||||
<dialog
|
||||
android:id="@+id/objectCoverUnsplashScreen"
|
||||
android:name="com.anytypeio.anytype.ui.editor.cover.ObjectUnsplashFragment"
|
||||
android:label="Object-Cover-Unsplash-Screen"/>
|
||||
<dialog
|
||||
android:id="@+id/relationAddToObjectBlockFragment"
|
||||
android:name="com.anytypeio.anytype.ui.relations.RelationAddToObjectBlockFragment"
|
||||
|
@ -111,6 +115,10 @@
|
|||
android:id="@+id/objectSetCoverScreen"
|
||||
android:name="com.anytypeio.anytype.ui.editor.cover.SelectCoverObjectSetFragment"
|
||||
android:label="Object-Cover-Screen"/>
|
||||
<dialog
|
||||
android:id="@+id/objectCoverUnsplashScreen"
|
||||
android:name="com.anytypeio.anytype.ui.editor.cover.ObjectSetUnsplashFragment"
|
||||
android:label="Object-Cover-Unsplash-Screen"/>
|
||||
<dialog
|
||||
android:id="@+id/viewerCardSizeSelectFragment"
|
||||
android:name="com.anytypeio.anytype.ui.sets.modals.viewer.ViewerCardSizeSelectFragment"
|
||||
|
|
|
@ -39,4 +39,5 @@
|
|||
<dimen name="default_dashboard_card_height">126dp</dimen>
|
||||
<dimen name="dashboard_object_icon_default_size">48dp</dimen>
|
||||
<dimen name="default_divider_height">0.5dp</dimen>
|
||||
<dimen name="default_search_toolbar_clip_height">36dp</dimen>
|
||||
</resources>
|
|
@ -268,4 +268,5 @@ Do the computation of an expensive paragraph of text on a background thread:
|
|||
<string name="anytype_analytics_msg">Understanding how people use Anytype helps us improve the product. This version of Anytype includes the analytics code that protects your privacy.\nIt doesn\'t record the actual document\'s content but still allows us to understand how you use Anytype.\nStay subscribed to our mailing list, as we will soon announce a new release that enables you to opt-out.</string>
|
||||
<string name="retry">Retry</string>
|
||||
<string name="limit_object_types">Limit object types</string>
|
||||
<string name="unsplash">Unsplash</string>
|
||||
</resources>
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package com.anytypeio.anytype.core_models
|
||||
|
||||
data class UnsplashImage(
|
||||
val id: Id,
|
||||
val url: Url,
|
||||
val artist: Artist,
|
||||
) {
|
||||
data class Artist(
|
||||
val name: String,
|
||||
val url: Url
|
||||
)
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.anytypeio.anytype.core_ui.features.cover
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.anytypeio.anytype.core_models.UnsplashImage
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.databinding.ItemCoverUnsplashImageBinding
|
||||
import com.anytypeio.anytype.core_utils.ext.dimen
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||
|
||||
class UnsplashImageAdapter(
|
||||
private val onImageClicked: (UnsplashImage) -> Unit
|
||||
) : ListAdapter<UnsplashImage, UnsplashImageAdapter.ViewHolder>(Differ) {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder = ViewHolder(
|
||||
binding = ItemCoverUnsplashImageBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
).apply {
|
||||
itemView.setOnClickListener {
|
||||
val pos = bindingAdapterPosition
|
||||
if (pos != RecyclerView.NO_POSITION)
|
||||
onImageClicked(getItem(pos))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
holder.bind(getItem(position))
|
||||
}
|
||||
|
||||
class ViewHolder(
|
||||
val binding: ItemCoverUnsplashImageBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun bind(item: UnsplashImage) = with(binding) {
|
||||
tvName.text = item.artist.name
|
||||
Glide.with(ivImage)
|
||||
.load(item.url)
|
||||
.placeholder(R.drawable.rect_unsplash_image_placeholder)
|
||||
.transform(CenterCrop(), RoundedCorners(dimen(R.dimen.dp_4)))
|
||||
.into(ivImage)
|
||||
}
|
||||
}
|
||||
|
||||
object Differ : DiffUtil.ItemCallback<UnsplashImage>() {
|
||||
override fun areItemsTheSame(oldItem: UnsplashImage, newItem: UnsplashImage): Boolean {
|
||||
return oldItem.id == newItem.id
|
||||
}
|
||||
override fun areContentsTheSame(oldItem: UnsplashImage, newItem: UnsplashImage): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.anytypeio.anytype.core_ui.widgets
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.FrameLayout
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.databinding.WidgetDefaultSearchToolbarBinding
|
||||
|
||||
class DefaultSearchToolbar @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null
|
||||
) : FrameLayout(context, attrs) {
|
||||
|
||||
val binding = WidgetDefaultSearchToolbarBinding.inflate(
|
||||
LayoutInflater.from(context), this
|
||||
)
|
||||
|
||||
init {
|
||||
setBackgroundResource(R.drawable.rect_search_input)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<stroke
|
||||
android:width="0.5dp"
|
||||
android:color="@color/shape_primary"
|
||||
android:dashWidth="0.5dp"/>
|
||||
<corners android:radius="4dp"/>
|
||||
</shape>
|
|
@ -72,6 +72,14 @@
|
|||
|
||||
</FrameLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:theme="@style/WhiteProgressBar"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<com.anytypeio.anytype.core_ui.widgets.text.TextInputWidget
|
||||
|
|
26
core-ui/src/main/res/layout/item_cover_unsplash_image.xml
Normal file
26
core-ui/src/main/res/layout/item_cover_unsplash_image.xml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="112dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivImage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:adjustViewBounds="true"
|
||||
android:contentDescription="@string/content_description_cover_image_view"
|
||||
tools:background="@color/black" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:fontFamily="@font/inter_medium"
|
||||
android:textColor="@color/white"
|
||||
tools:text="Yves Klein" />
|
||||
|
||||
</FrameLayout>
|
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/searchIcon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="6dp"
|
||||
android:background="@drawable/ic_search" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/filterInputField"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:background="@null"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
android:hint="@string/search"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:textColorHint="@color/text_tertiary"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textSize="17sp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/searchIcon"
|
||||
app:layout_constraintEnd_toStartOf="@+id/clearSearchText"
|
||||
app:layout_constraintStart_toEndOf="@+id/searchIcon"
|
||||
app:layout_constraintTop_toTopOf="@+id/searchIcon"
|
||||
app:layout_goneMarginEnd="@dimen/dp_16" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/clearSearchText"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:src="@drawable/ic_search_delete"
|
||||
android:visibility="invisible"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:theme="@style/GreyProgressBar"
|
||||
android:visibility="invisible"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</merge>
|
|
@ -373,6 +373,10 @@
|
|||
<item name="colorAccent">@color/text_secondary</item>
|
||||
</style>
|
||||
|
||||
<style name="WhiteProgressBar" parent="ThemeOverlay.AppCompat.Light">
|
||||
<item name="colorAccent">@color/white</item>
|
||||
</style>
|
||||
|
||||
<style name="GridCellDateTextStyle">
|
||||
<item name="android:textColor">@color/text_primary</item>
|
||||
<item name="android:maxLines">1</item>
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package com.anytypeio.anytype.data.auth.repo.unsplash
|
||||
|
||||
import com.anytypeio.anytype.core_models.Hash
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.UnsplashImage
|
||||
import com.anytypeio.anytype.domain.unsplash.UnsplashRepository
|
||||
|
||||
class UnsplashDataRepository(
|
||||
private val remote: UnsplashRemote
|
||||
) : UnsplashRepository {
|
||||
override fun search(
|
||||
query: String,
|
||||
limit: Int
|
||||
): List<UnsplashImage> = remote.search(
|
||||
query = query,
|
||||
limit = limit
|
||||
)
|
||||
override fun download(id: Id) : Hash = remote.download(id = id)
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.anytypeio.anytype.data.auth.repo.unsplash
|
||||
|
||||
import com.anytypeio.anytype.core_models.Hash
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.UnsplashImage
|
||||
|
||||
interface UnsplashRemote {
|
||||
fun search(query: String, limit: Int) : List<UnsplashImage>
|
||||
fun download(id: Id) : Hash
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.anytypeio.anytype.domain.unsplash
|
||||
|
||||
import com.anytypeio.anytype.core_models.Hash
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.domain.base.BaseUseCase
|
||||
|
||||
class DownloadUnsplashImage(
|
||||
private val repo: UnsplashRepository
|
||||
) : BaseUseCase<Hash, DownloadUnsplashImage.Params>() {
|
||||
|
||||
override suspend fun run(params: Params) = safe {
|
||||
repo.download(params.picture)
|
||||
}
|
||||
|
||||
class Params(val picture: Id)
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.anytypeio.anytype.domain.unsplash
|
||||
|
||||
import com.anytypeio.anytype.core_models.UnsplashImage
|
||||
import com.anytypeio.anytype.domain.base.BaseUseCase
|
||||
|
||||
class SearchUnsplashImage(
|
||||
private val repo: UnsplashRepository
|
||||
) : BaseUseCase<List<UnsplashImage>, SearchUnsplashImage.Params>() {
|
||||
|
||||
override suspend fun run(params: Params) = safe {
|
||||
repo.search(query = params.query, limit = params.limit)
|
||||
}
|
||||
|
||||
class Params(
|
||||
val query: String,
|
||||
val limit: Int = DEFAULT_LIMIT
|
||||
)
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_LIMIT = 36
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.anytypeio.anytype.domain.unsplash
|
||||
|
||||
import com.anytypeio.anytype.core_models.Hash
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.UnsplashImage
|
||||
|
||||
interface UnsplashRepository {
|
||||
fun search(query: String, limit: Int) : List<UnsplashImage>
|
||||
fun download(id: Id) : Hash
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.anytypeio.anytype.middleware
|
||||
|
||||
import anytype.Rpc
|
||||
import anytype.Rpc.UnsplashSearch
|
||||
import com.anytypeio.anytype.core_models.Hash
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.UnsplashImage
|
||||
import com.anytypeio.anytype.data.auth.repo.unsplash.UnsplashRemote
|
||||
import com.anytypeio.anytype.middleware.log.logRequest
|
||||
import com.anytypeio.anytype.middleware.log.logResponse
|
||||
import com.anytypeio.anytype.middleware.mappers.core
|
||||
import com.anytypeio.anytype.middleware.service.MiddlewareService
|
||||
|
||||
class UnsplashMiddleware(
|
||||
private val service: MiddlewareService
|
||||
) : UnsplashRemote {
|
||||
|
||||
override fun search(query: String, limit: Int): List<UnsplashImage> {
|
||||
val request = UnsplashSearch.Request(
|
||||
query = query,
|
||||
limit = limit
|
||||
).also { it.logRequest() }
|
||||
val response = service.unsplashSearch(request = request).also { it.logResponse() }
|
||||
return response.pictures.map { p -> p.core() }
|
||||
}
|
||||
|
||||
override fun download(id: Id): Hash {
|
||||
val request = Rpc.UnsplashDownload.Request(pictureId = id).also { it.logRequest() }
|
||||
val response = service.unsplashDownload(request = request).also { it.logResponse() }
|
||||
return response.hash
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.anytypeio.anytype.middleware.log
|
||||
|
||||
import timber.log.Timber
|
||||
|
||||
fun Any.logResponse() {
|
||||
val message = "===> " + this::class.java.canonicalName + ":" + "\n" + this.toString()
|
||||
Timber.d(message)
|
||||
}
|
||||
|
||||
fun Any.logRequest() {
|
||||
val message = "<=== " + this::class.java.canonicalName + ":" + "\n" + this.toString()
|
||||
Timber.d(message)
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.anytypeio.anytype.middleware.mappers
|
||||
|
||||
import anytype.Rpc.UnsplashSearch.Response.Picture
|
||||
import com.anytypeio.anytype.core_models.UnsplashImage
|
||||
|
||||
fun Picture.core() : UnsplashImage = UnsplashImage(
|
||||
id = id,
|
||||
url = url,
|
||||
artist = UnsplashImage.Artist(
|
||||
name = artist,
|
||||
url = artistUrl
|
||||
)
|
||||
)
|
|
@ -227,4 +227,10 @@ interface MiddlewareService {
|
|||
|
||||
@Throws(Exception::class)
|
||||
fun fileListOffload(request: FileList.Offload.Request): FileList.Offload.Response
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun unsplashSearch(request: UnsplashSearch.Request) : UnsplashSearch.Response
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun unsplashDownload(request: UnsplashDownload.Request) : UnsplashDownload.Response
|
||||
}
|
|
@ -920,4 +920,30 @@ class MiddlewareServiceImplementation : MiddlewareService {
|
|||
return response
|
||||
}
|
||||
}
|
||||
|
||||
override fun unsplashSearch(request: UnsplashSearch.Request): UnsplashSearch.Response {
|
||||
val encoded = Service.unsplashSearch(
|
||||
UnsplashSearch.Request.ADAPTER.encode(request)
|
||||
)
|
||||
val response = UnsplashSearch.Response.ADAPTER.decode(encoded)
|
||||
val error = response.error
|
||||
if (error != null && error.code != UnsplashSearch.Response.Error.Code.NULL) {
|
||||
throw Exception(error.description)
|
||||
} else {
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
||||
override fun unsplashDownload(request: UnsplashDownload.Request): UnsplashDownload.Response {
|
||||
val encoded = Service.unsplashDownload(
|
||||
UnsplashDownload.Request.ADAPTER.encode(request)
|
||||
)
|
||||
val response = UnsplashDownload.Response.ADAPTER.decode(encoded)
|
||||
val error = response.error
|
||||
if (error != null && error.code != UnsplashDownload.Response.Error.Code.NULL) {
|
||||
throw Exception(error.description)
|
||||
} else {
|
||||
return response
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.anytypeio.anytype.presentation.common
|
||||
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
|
||||
interface Delegator<T> {
|
||||
val channel : SharedFlow<T>
|
||||
suspend fun delegate(action: T)
|
||||
suspend fun receive() : Flow<T> = channel
|
||||
class Default<T> : Delegator<T> {
|
||||
override val channel = MutableSharedFlow<T>()
|
||||
override suspend fun delegate(action: T) {
|
||||
channel.emit(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class Action {
|
||||
data class SetUnsplashImage(val img: Id) : Action()
|
||||
}
|
|
@ -25,6 +25,7 @@ import com.anytypeio.anytype.domain.block.interactor.RemoveLinkMark
|
|||
import com.anytypeio.anytype.domain.block.interactor.UpdateLinkMarks
|
||||
import com.anytypeio.anytype.domain.block.interactor.UpdateText
|
||||
import com.anytypeio.anytype.domain.block.interactor.sets.CreateObjectSet
|
||||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.GetCompatibleObjectTypes
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.SearchObjects
|
||||
import com.anytypeio.anytype.domain.editor.Editor
|
||||
|
@ -36,7 +37,10 @@ import com.anytypeio.anytype.domain.objects.SetObjectIsArchived
|
|||
import com.anytypeio.anytype.domain.page.*
|
||||
import com.anytypeio.anytype.domain.sets.FindObjectSetForType
|
||||
import com.anytypeio.anytype.domain.status.InterceptThreadStatus
|
||||
import com.anytypeio.anytype.domain.unsplash.DownloadUnsplashImage
|
||||
import com.anytypeio.anytype.presentation.BuildConfig
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.common.StateReducer
|
||||
import com.anytypeio.anytype.presentation.common.SupportCommand
|
||||
import com.anytypeio.anytype.presentation.editor.ControlPanelMachine.Interactor
|
||||
|
@ -123,6 +127,7 @@ class EditorViewModel(
|
|||
private val orchestrator: Orchestrator,
|
||||
private val analytics: Analytics,
|
||||
private val dispatcher: Dispatcher<Payload>,
|
||||
private val delegator: Delegator<Action>,
|
||||
private val detailModificationManager: DetailModificationManager,
|
||||
private val updateDetail: UpdateDetail,
|
||||
private val getCompatibleObjectTypes: GetCompatibleObjectTypes,
|
||||
|
@ -131,7 +136,9 @@ class EditorViewModel(
|
|||
private val getDefaultEditorType: GetDefaultEditorType,
|
||||
private val findObjectSetForType: FindObjectSetForType,
|
||||
private val createObjectSet: CreateObjectSet,
|
||||
private val copyFileToCache: CopyFileToCacheDirectory
|
||||
private val copyFileToCache: CopyFileToCacheDirectory,
|
||||
private val downloadUnsplashImage: DownloadUnsplashImage,
|
||||
private val setDocCoverImage: SetDocCoverImage
|
||||
) : ViewStateViewModel<ViewState>(),
|
||||
SupportNavigation<EventWrapper<AppNavigation.Command>>,
|
||||
SupportCommand<Command>,
|
||||
|
@ -224,6 +231,43 @@ class EditorViewModel(
|
|||
processRendering()
|
||||
processMarkupChanges()
|
||||
viewModelScope.launch { orchestrator.start() }
|
||||
|
||||
viewModelScope.launch {
|
||||
delegator.receive().collect { action ->
|
||||
when (action) {
|
||||
is Action.SetUnsplashImage -> {
|
||||
proceedWithSettingUnsplashImage(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun proceedWithSettingUnsplashImage(
|
||||
action: Action.SetUnsplashImage
|
||||
) {
|
||||
downloadUnsplashImage(
|
||||
DownloadUnsplashImage.Params(
|
||||
picture = action.img
|
||||
)
|
||||
).process(
|
||||
failure = {
|
||||
Timber.e(it, "Error while download unsplash image")
|
||||
},
|
||||
success = { hash ->
|
||||
setDocCoverImage(
|
||||
SetDocCoverImage.Params.FromHash(
|
||||
context = context,
|
||||
hash = hash
|
||||
)
|
||||
).process(
|
||||
failure = {
|
||||
Timber.e(it, "Error while setting unsplash image")
|
||||
},
|
||||
success = { payload -> dispatcher.send(payload) }
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun startProcessingInternalDetailModifications() {
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.anytypeio.anytype.domain.`object`.UpdateDetail
|
|||
import com.anytypeio.anytype.domain.block.interactor.RemoveLinkMark
|
||||
import com.anytypeio.anytype.domain.block.interactor.UpdateLinkMarks
|
||||
import com.anytypeio.anytype.domain.block.interactor.sets.CreateObjectSet
|
||||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.GetCompatibleObjectTypes
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.SearchObjects
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
|
@ -20,6 +21,9 @@ import com.anytypeio.anytype.domain.objects.SetObjectIsArchived
|
|||
import com.anytypeio.anytype.domain.page.*
|
||||
import com.anytypeio.anytype.domain.sets.FindObjectSetForType
|
||||
import com.anytypeio.anytype.domain.status.InterceptThreadStatus
|
||||
import com.anytypeio.anytype.domain.unsplash.DownloadUnsplashImage
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.common.StateReducer
|
||||
import com.anytypeio.anytype.presentation.editor.editor.DetailModificationManager
|
||||
import com.anytypeio.anytype.presentation.editor.editor.Orchestrator
|
||||
|
@ -46,6 +50,7 @@ open class EditorViewModelFactory(
|
|||
private val orchestrator: Orchestrator,
|
||||
private val analytics: Analytics,
|
||||
private val dispatcher: Dispatcher<Payload>,
|
||||
private val delegator: Delegator<Action>,
|
||||
private val detailModificationManager: DetailModificationManager,
|
||||
private val updateDetail: UpdateDetail,
|
||||
private val getCompatibleObjectTypes: GetCompatibleObjectTypes,
|
||||
|
@ -53,7 +58,9 @@ open class EditorViewModelFactory(
|
|||
private val searchObjects: SearchObjects,
|
||||
private val getDefaultEditorType: GetDefaultEditorType,
|
||||
private val findObjectSetForType: FindObjectSetForType,
|
||||
private val copyFileToCacheDirectory: CopyFileToCacheDirectory
|
||||
private val copyFileToCacheDirectory: CopyFileToCacheDirectory,
|
||||
private val downloadUnsplashImage: DownloadUnsplashImage,
|
||||
private val setDocCoverImage: SetDocCoverImage
|
||||
) : ViewModelProvider.Factory {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
@ -76,6 +83,7 @@ open class EditorViewModelFactory(
|
|||
orchestrator = orchestrator,
|
||||
analytics = analytics,
|
||||
dispatcher = dispatcher,
|
||||
delegator = delegator,
|
||||
detailModificationManager = detailModificationManager,
|
||||
updateDetail = updateDetail,
|
||||
getCompatibleObjectTypes = getCompatibleObjectTypes,
|
||||
|
@ -84,7 +92,9 @@ open class EditorViewModelFactory(
|
|||
getDefaultEditorType = getDefaultEditorType,
|
||||
findObjectSetForType = findObjectSetForType,
|
||||
createObjectSet = createObjectSet,
|
||||
copyFileToCache = copyFileToCacheDirectory
|
||||
copyFileToCache = copyFileToCacheDirectory,
|
||||
downloadUnsplashImage = downloadUnsplashImage,
|
||||
setDocCoverImage = setDocCoverImage
|
||||
) as T
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package com.anytypeio.anytype.presentation.editor.cover
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.UnsplashImage
|
||||
import com.anytypeio.anytype.domain.unsplash.SearchUnsplashImage
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.BaseViewModel
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
class UnsplashViewModel(
|
||||
private val search: SearchUnsplashImage,
|
||||
private val delegator: Delegator<Action>
|
||||
) : BaseViewModel() {
|
||||
|
||||
val isCompleted = MutableStateFlow(false)
|
||||
|
||||
private val input = MutableStateFlow("")
|
||||
|
||||
private val query = input.take(1).onCompletion {
|
||||
emitAll(
|
||||
input.debounce(DEBOUNCE_DURATION).distinctUntilChanged()
|
||||
)
|
||||
}
|
||||
|
||||
val images = MutableStateFlow<List<UnsplashImage>>(emptyList())
|
||||
val isLoading = MutableStateFlow(false)
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
query.mapLatest { q ->
|
||||
isLoading.value = true
|
||||
search(
|
||||
SearchUnsplashImage.Params(
|
||||
query = q
|
||||
)
|
||||
).process(
|
||||
failure = {
|
||||
Timber.e(it, "Error while searching unsplash pictures")
|
||||
},
|
||||
success = {
|
||||
images.value = it
|
||||
}
|
||||
).also {
|
||||
isLoading.value = false
|
||||
}
|
||||
}.collect()
|
||||
}
|
||||
}
|
||||
|
||||
fun onImageSelected(ctx: Id, img: UnsplashImage) {
|
||||
viewModelScope.launch {
|
||||
delegator.delegate(
|
||||
Action.SetUnsplashImage(img.id)
|
||||
)
|
||||
isCompleted.value = true
|
||||
}
|
||||
}
|
||||
|
||||
fun onQueryChanged(query: String) {
|
||||
viewModelScope.launch {
|
||||
input.emit(query)
|
||||
}
|
||||
}
|
||||
|
||||
class Factory(
|
||||
private val search: SearchUnsplashImage,
|
||||
private val delegator: Delegator<Action>,
|
||||
) : ViewModelProvider.Factory {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return UnsplashViewModel(
|
||||
search = search,
|
||||
delegator = delegator,
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val DEBOUNCE_DURATION = 300L
|
||||
}
|
||||
}
|
|
@ -32,7 +32,7 @@ open class ObjectSearchViewModel(
|
|||
) : ViewStateViewModel<ObjectSearchView>(),
|
||||
SupportNavigation<EventWrapper<AppNavigation.Command>> {
|
||||
|
||||
private val userInput = MutableStateFlow(EMPTY_QUERY)
|
||||
private val userInput = MutableStateFlow(EMPTY_QUERY)
|
||||
private val searchQuery = userInput
|
||||
.take(1)
|
||||
.onCompletion {
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.anytypeio.anytype.core_models.restrictions.DataViewRestriction
|
|||
import com.anytypeio.anytype.core_utils.common.EventWrapper
|
||||
import com.anytypeio.anytype.domain.base.Result
|
||||
import com.anytypeio.anytype.domain.block.interactor.UpdateText
|
||||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.*
|
||||
import com.anytypeio.anytype.domain.error.Error
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
|
@ -18,6 +19,9 @@ import com.anytypeio.anytype.domain.misc.UrlBuilder
|
|||
import com.anytypeio.anytype.domain.page.CloseBlock
|
||||
import com.anytypeio.anytype.domain.sets.OpenObjectSet
|
||||
import com.anytypeio.anytype.domain.status.InterceptThreadStatus
|
||||
import com.anytypeio.anytype.domain.unsplash.DownloadUnsplashImage
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.editor.editor.Proxy
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.editor.model.TextUpdate
|
||||
|
@ -48,10 +52,13 @@ class ObjectSetViewModel(
|
|||
private val updateDataViewViewer: UpdateDataViewViewer,
|
||||
private val updateDataViewRecord: UpdateDataViewRecord,
|
||||
private val createDataViewRecord: CreateDataViewRecord,
|
||||
private val downloadUnsplashImage: DownloadUnsplashImage,
|
||||
private val setDocCoverImage: SetDocCoverImage,
|
||||
private val updateText: UpdateText,
|
||||
private val interceptEvents: InterceptEvents,
|
||||
private val interceptThreadStatus: InterceptThreadStatus,
|
||||
private val dispatcher: Dispatcher<Payload>,
|
||||
private val delegator: Delegator<Action>,
|
||||
private val objectSetRecordCache: ObjectSetRecordCache,
|
||||
private val urlBuilder: UrlBuilder,
|
||||
private val session: ObjectSetSession,
|
||||
|
@ -177,6 +184,43 @@ class ObjectSetViewModel(
|
|||
}
|
||||
.collect()
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
delegator.receive().collect { action ->
|
||||
when (action) {
|
||||
is Action.SetUnsplashImage -> {
|
||||
proceedWithSettingUnsplashImage(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun proceedWithSettingUnsplashImage(
|
||||
action: Action.SetUnsplashImage
|
||||
) {
|
||||
downloadUnsplashImage(
|
||||
DownloadUnsplashImage.Params(
|
||||
picture = action.img
|
||||
)
|
||||
).process(
|
||||
failure = {
|
||||
Timber.e(it, "Error while download unsplash image")
|
||||
},
|
||||
success = { hash ->
|
||||
setDocCoverImage(
|
||||
SetDocCoverImage.Params.FromHash(
|
||||
context = context,
|
||||
hash = hash
|
||||
)
|
||||
).process(
|
||||
failure = {
|
||||
Timber.e(it, "Error while setting unsplash image")
|
||||
},
|
||||
success = { payload -> dispatcher.send(payload) }
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun onStart(ctx: Id) {
|
||||
|
|
|
@ -5,12 +5,16 @@ import androidx.lifecycle.ViewModelProvider
|
|||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.domain.block.interactor.UpdateText
|
||||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.*
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.page.CloseBlock
|
||||
import com.anytypeio.anytype.domain.sets.OpenObjectSet
|
||||
import com.anytypeio.anytype.domain.status.InterceptThreadStatus
|
||||
import com.anytypeio.anytype.domain.unsplash.DownloadUnsplashImage
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.util.Dispatcher
|
||||
|
||||
class ObjectSetViewModelFactory(
|
||||
|
@ -22,10 +26,13 @@ class ObjectSetViewModelFactory(
|
|||
private val updateDataViewViewer: UpdateDataViewViewer,
|
||||
private val updateDataViewRecord: UpdateDataViewRecord,
|
||||
private val createDataViewRecord: CreateDataViewRecord,
|
||||
private val downloadUnsplashImage: DownloadUnsplashImage,
|
||||
private val setDocCoverImage: SetDocCoverImage,
|
||||
private val updateText: UpdateText,
|
||||
private val interceptEvents: InterceptEvents,
|
||||
private val interceptThreadStatus: InterceptThreadStatus,
|
||||
private val dispatcher: Dispatcher<Payload>,
|
||||
private val delegator: Delegator<Action>,
|
||||
private val objectSetRecordCache: ObjectSetRecordCache,
|
||||
private val urlBuilder: UrlBuilder,
|
||||
private val session: ObjectSetSession,
|
||||
|
@ -42,10 +49,13 @@ class ObjectSetViewModelFactory(
|
|||
updateDataViewViewer = updateDataViewViewer,
|
||||
updateDataViewRecord = updateDataViewRecord,
|
||||
createDataViewRecord = createDataViewRecord,
|
||||
setDocCoverImage = setDocCoverImage,
|
||||
downloadUnsplashImage = downloadUnsplashImage,
|
||||
updateText = updateText,
|
||||
interceptEvents = interceptEvents,
|
||||
interceptThreadStatus = interceptThreadStatus,
|
||||
dispatcher = dispatcher,
|
||||
delegator = delegator,
|
||||
objectSetRecordCache = objectSetRecordCache,
|
||||
urlBuilder = urlBuilder,
|
||||
session = session,
|
||||
|
|
|
@ -16,6 +16,7 @@ import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
|||
import com.anytypeio.anytype.domain.clipboard.Copy
|
||||
import com.anytypeio.anytype.domain.clipboard.Paste
|
||||
import com.anytypeio.anytype.domain.config.Gateway
|
||||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.GetCompatibleObjectTypes
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.SearchObjects
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.SetRelationKey
|
||||
|
@ -29,7 +30,11 @@ import com.anytypeio.anytype.domain.page.bookmark.CreateBookmark
|
|||
import com.anytypeio.anytype.domain.page.bookmark.SetupBookmark
|
||||
import com.anytypeio.anytype.domain.sets.FindObjectSetForType
|
||||
import com.anytypeio.anytype.domain.status.InterceptThreadStatus
|
||||
import com.anytypeio.anytype.domain.unsplash.DownloadUnsplashImage
|
||||
import com.anytypeio.anytype.domain.unsplash.UnsplashRepository
|
||||
import com.anytypeio.anytype.presentation.MockBlockFactory
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.editor.cover.CoverImageHashProvider
|
||||
import com.anytypeio.anytype.presentation.editor.editor.*
|
||||
import com.anytypeio.anytype.presentation.editor.editor.Command
|
||||
|
@ -212,6 +217,9 @@ open class EditorViewModelTest {
|
|||
@Mock
|
||||
lateinit var repo: BlockRepository
|
||||
|
||||
@Mock
|
||||
lateinit var unsplashRepo: UnsplashRepository
|
||||
|
||||
@Mock
|
||||
lateinit var setObjectType: SetObjectType
|
||||
|
||||
|
@ -238,9 +246,13 @@ open class EditorViewModelTest {
|
|||
lateinit var vm: EditorViewModel
|
||||
|
||||
private lateinit var builder: UrlBuilder
|
||||
private lateinit var downloadUnsplashImage: DownloadUnsplashImage
|
||||
private lateinit var setDocCoverImage: SetDocCoverImage
|
||||
|
||||
val root = MockDataFactory.randomUuid()
|
||||
|
||||
val delegator = Delegator.Default<Action>()
|
||||
|
||||
val title = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
content = Block.Content.Text(
|
||||
|
@ -3918,6 +3930,8 @@ open class EditorViewModelTest {
|
|||
selections = SelectionStateHolder.Default()
|
||||
)
|
||||
updateDetail = UpdateDetail(repo)
|
||||
setDocCoverImage = SetDocCoverImage(repo)
|
||||
downloadUnsplashImage = DownloadUnsplashImage(unsplashRepo)
|
||||
|
||||
vm = EditorViewModel(
|
||||
openPage = openPage,
|
||||
|
@ -3988,7 +4002,10 @@ open class EditorViewModelTest {
|
|||
searchObjects = searchObjects,
|
||||
findObjectSetForType = findObjectSetForType,
|
||||
createObjectSet = createObjectSet,
|
||||
copyFileToCache = copyFileToCacheDirectory
|
||||
copyFileToCache = copyFileToCacheDirectory,
|
||||
downloadUnsplashImage = downloadUnsplashImage,
|
||||
setDocCoverImage = setDocCoverImage,
|
||||
delegator = delegator
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
|||
import com.anytypeio.anytype.domain.clipboard.Copy
|
||||
import com.anytypeio.anytype.domain.clipboard.Paste
|
||||
import com.anytypeio.anytype.domain.config.Gateway
|
||||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.GetCompatibleObjectTypes
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.SearchObjects
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.SetRelationKey
|
||||
|
@ -28,6 +29,10 @@ import com.anytypeio.anytype.domain.page.bookmark.CreateBookmark
|
|||
import com.anytypeio.anytype.domain.page.bookmark.SetupBookmark
|
||||
import com.anytypeio.anytype.domain.sets.FindObjectSetForType
|
||||
import com.anytypeio.anytype.domain.status.InterceptThreadStatus
|
||||
import com.anytypeio.anytype.domain.unsplash.DownloadUnsplashImage
|
||||
import com.anytypeio.anytype.domain.unsplash.UnsplashRepository
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.editor.DocumentExternalEventReducer
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
import com.anytypeio.anytype.presentation.editor.EditorViewModel
|
||||
|
@ -176,6 +181,9 @@ open class EditorPresentationTestSetup {
|
|||
@Mock
|
||||
lateinit var repo: BlockRepository
|
||||
|
||||
@Mock
|
||||
lateinit var unsplashRepo: UnsplashRepository
|
||||
|
||||
@Mock
|
||||
lateinit var getCompatibleObjectTypes: GetCompatibleObjectTypes
|
||||
|
||||
|
@ -206,9 +214,13 @@ open class EditorPresentationTestSetup {
|
|||
protected val builder: UrlBuilder get() = UrlBuilder(gateway)
|
||||
|
||||
private lateinit var updateDetail: UpdateDetail
|
||||
private lateinit var downloadUnsplashImage: DownloadUnsplashImage
|
||||
private lateinit var setDocCoverImage: SetDocCoverImage
|
||||
|
||||
open lateinit var orchestrator: Orchestrator
|
||||
|
||||
private val delegator = Delegator.Default<Action>()
|
||||
|
||||
open fun buildViewModel(urlBuilder: UrlBuilder = builder): EditorViewModel {
|
||||
|
||||
val storage = Editor.Storage()
|
||||
|
@ -217,6 +229,8 @@ open class EditorPresentationTestSetup {
|
|||
selections = SelectionStateHolder.Default()
|
||||
)
|
||||
updateDetail = UpdateDetail(repo)
|
||||
setDocCoverImage = SetDocCoverImage(repo)
|
||||
downloadUnsplashImage = DownloadUnsplashImage(unsplashRepo)
|
||||
|
||||
orchestrator = Orchestrator(
|
||||
createBlock = createBlock,
|
||||
|
@ -289,7 +303,10 @@ open class EditorPresentationTestSetup {
|
|||
getDefaultEditorType = getDefaultEditorType,
|
||||
findObjectSetForType = findObjectSetForType,
|
||||
createObjectSet = createObjectSet,
|
||||
copyFileToCache = copyFileToCacheDirectory
|
||||
copyFileToCache = copyFileToCacheDirectory,
|
||||
delegator = delegator,
|
||||
setDocCoverImage = setDocCoverImage,
|
||||
downloadUnsplashImage = downloadUnsplashImage
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -8,12 +8,16 @@ import com.anytypeio.anytype.domain.base.Either
|
|||
import com.anytypeio.anytype.domain.base.Result
|
||||
import com.anytypeio.anytype.domain.block.interactor.UpdateText
|
||||
import com.anytypeio.anytype.domain.config.Gateway
|
||||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.*
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.page.CloseBlock
|
||||
import com.anytypeio.anytype.domain.sets.OpenObjectSet
|
||||
import com.anytypeio.anytype.domain.status.InterceptThreadStatus
|
||||
import com.anytypeio.anytype.domain.unsplash.DownloadUnsplashImage
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.sets.ObjectSetRecordCache
|
||||
import com.anytypeio.anytype.presentation.sets.ObjectSetReducer
|
||||
import com.anytypeio.anytype.presentation.sets.ObjectSetSession
|
||||
|
@ -67,7 +71,14 @@ open class ObjectSetViewModelTestSetup {
|
|||
@Mock
|
||||
lateinit var analytics: Analytics
|
||||
|
||||
@Mock
|
||||
lateinit var downloadUnsplashImage: DownloadUnsplashImage
|
||||
|
||||
@Mock
|
||||
lateinit var setDocCoverImage: SetDocCoverImage
|
||||
|
||||
val dispatcher = Dispatcher.Default<Payload>()
|
||||
val delegator = Delegator.Default<Action>()
|
||||
val reducer = ObjectSetReducer()
|
||||
val cache = ObjectSetRecordCache()
|
||||
val session = ObjectSetSession()
|
||||
|
@ -87,11 +98,14 @@ open class ObjectSetViewModelTestSetup {
|
|||
createDataViewRecord = createDataViewRecord,
|
||||
setActiveViewer = setActiveViewer,
|
||||
dispatcher = dispatcher,
|
||||
delegator = delegator,
|
||||
reducer = reducer,
|
||||
objectSetRecordCache = cache,
|
||||
urlBuilder = urlBuilder,
|
||||
session = session,
|
||||
analytics = analytics
|
||||
analytics = analytics,
|
||||
downloadUnsplashImage = downloadUnsplashImage,
|
||||
setDocCoverImage = setDocCoverImage
|
||||
)
|
||||
|
||||
fun stubInterceptEvents(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue