mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-2734 Global search | Save search query, related to state (#1541)
This commit is contained in:
parent
0544fb7cf9
commit
6f6c08b0bb
37 changed files with 591 additions and 419 deletions
|
@ -82,7 +82,6 @@ import com.anytypeio.anytype.domain.page.bookmark.CreateBookmarkBlock
|
|||
import com.anytypeio.anytype.domain.page.bookmark.SetupBookmark
|
||||
import com.anytypeio.anytype.domain.relations.AddRelationToObject
|
||||
import com.anytypeio.anytype.domain.relations.SetRelationKey
|
||||
import com.anytypeio.anytype.domain.search.GetLastSearchQuery
|
||||
import com.anytypeio.anytype.domain.search.SearchObjects
|
||||
import com.anytypeio.anytype.domain.sets.FindObjectSetForType
|
||||
import com.anytypeio.anytype.domain.table.CreateTable
|
||||
|
@ -295,9 +294,6 @@ open class EditorTestSetup {
|
|||
@Mock
|
||||
lateinit var spaceSyncAndP2PStatusProvider: SpaceSyncAndP2PStatusProvider
|
||||
|
||||
@Mock
|
||||
lateinit var getLastSearchQuery: GetLastSearchQuery
|
||||
|
||||
lateinit var interceptFileLimitEvents: InterceptFileLimitEvents
|
||||
|
||||
lateinit var addRelationToObject: AddRelationToObject
|
||||
|
@ -502,8 +498,7 @@ open class EditorTestSetup {
|
|||
syncStatusProvider = spaceSyncAndP2PStatusProvider,
|
||||
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate,
|
||||
clearLastOpenedObject = clearLastOpenedObject,
|
||||
getNetworkMode = getNetworkMode,
|
||||
getLastSearchQuery = getLastSearchQuery
|
||||
getNetworkMode = getNetworkMode
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ import com.anytypeio.anytype.domain.page.CloseBlock
|
|||
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.GetLastSearchQuery
|
||||
import com.anytypeio.anytype.domain.search.SubscriptionEventChannel
|
||||
import com.anytypeio.anytype.domain.sets.OpenObjectSet
|
||||
import com.anytypeio.anytype.domain.sets.SetQueryToObjectSet
|
||||
|
@ -186,9 +185,6 @@ abstract class TestObjectSetSetup {
|
|||
@Mock
|
||||
lateinit var clearLastOpenedObject: ClearLastOpenedObject
|
||||
|
||||
@Mock
|
||||
lateinit var getLastSearchQuery: GetLastSearchQuery
|
||||
|
||||
private lateinit var getTemplates: GetTemplates
|
||||
private lateinit var getDefaultObjectType: GetDefaultObjectType
|
||||
|
||||
|
@ -316,8 +312,7 @@ abstract class TestObjectSetSetup {
|
|||
permissions = permissions,
|
||||
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate,
|
||||
spaceSyncAndP2PStatusProvider = spaceSyncAndP2PStatusProvider,
|
||||
clearLastOpenedObject = clearLastOpenedObject,
|
||||
getLastSearchQuery = getLastSearchQuery
|
||||
clearLastOpenedObject = clearLastOpenedObject
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,6 @@ import com.anytypeio.anytype.domain.page.bookmark.SetupBookmark
|
|||
import com.anytypeio.anytype.domain.relations.AddFileToObject
|
||||
import com.anytypeio.anytype.domain.relations.AddRelationToObject
|
||||
import com.anytypeio.anytype.domain.relations.SetRelationKey
|
||||
import com.anytypeio.anytype.domain.search.GetLastSearchQuery
|
||||
import com.anytypeio.anytype.domain.search.SearchObjects
|
||||
import com.anytypeio.anytype.domain.sets.FindObjectSetForType
|
||||
import com.anytypeio.anytype.domain.table.CreateTable
|
||||
|
@ -293,8 +292,7 @@ object EditorSessionModule {
|
|||
analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate,
|
||||
syncStatusProvider: SpaceSyncAndP2PStatusProvider,
|
||||
getNetworkMode: GetNetworkMode,
|
||||
clearLastOpenedObject: ClearLastOpenedObject,
|
||||
getLastSearchQuery: GetLastSearchQuery
|
||||
clearLastOpenedObject: ClearLastOpenedObject
|
||||
): EditorViewModelFactory = EditorViewModelFactory(
|
||||
params = params,
|
||||
permissions = permissions,
|
||||
|
@ -340,8 +338,7 @@ object EditorSessionModule {
|
|||
getNetworkMode = getNetworkMode,
|
||||
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate,
|
||||
clearLastOpenedObject = clearLastOpenedObject,
|
||||
syncStatusProvider = syncStatusProvider,
|
||||
getLastSearchQuery = getLastSearchQuery
|
||||
syncStatusProvider = syncStatusProvider
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
@ -1204,14 +1201,6 @@ object EditorUseCaseModule {
|
|||
spaceManager = spaceManager
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerScreen
|
||||
fun provideGetLastSearchQueryUseCase(
|
||||
repo: UserSettingsRepository,
|
||||
dispatchers: AppCoroutineDispatchers
|
||||
): GetLastSearchQuery = GetLastSearchQuery(repo, dispatchers)
|
||||
|
||||
@Module
|
||||
interface Bindings {
|
||||
|
||||
|
|
|
@ -57,7 +57,6 @@ import com.anytypeio.anytype.domain.relations.AddRelationToObject
|
|||
import com.anytypeio.anytype.domain.relations.DeleteRelationFromDataView
|
||||
import com.anytypeio.anytype.domain.search.CancelSearchSubscription
|
||||
import com.anytypeio.anytype.domain.search.DataViewSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.search.GetLastSearchQuery
|
||||
import com.anytypeio.anytype.domain.search.SearchObjects
|
||||
import com.anytypeio.anytype.domain.search.SubscriptionEventChannel
|
||||
import com.anytypeio.anytype.domain.sets.OpenObjectSet
|
||||
|
@ -246,8 +245,7 @@ object ObjectSetModule {
|
|||
permissions: UserPermissionProvider,
|
||||
clearLastOpenedObject: ClearLastOpenedObject,
|
||||
analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate,
|
||||
spaceSyncAndP2PStatusProvider: SpaceSyncAndP2PStatusProvider,
|
||||
getLastSearchQuery: GetLastSearchQuery
|
||||
spaceSyncAndP2PStatusProvider: SpaceSyncAndP2PStatusProvider
|
||||
): ObjectSetViewModelFactory = ObjectSetViewModelFactory(
|
||||
params = params,
|
||||
openObjectSet = openObjectSet,
|
||||
|
@ -289,18 +287,9 @@ object ObjectSetModule {
|
|||
permissions = permissions,
|
||||
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate,
|
||||
spaceSyncAndP2PStatusProvider = spaceSyncAndP2PStatusProvider,
|
||||
clearLastOpenedObject = clearLastOpenedObject,
|
||||
getLastSearchQuery = getLastSearchQuery
|
||||
clearLastOpenedObject = clearLastOpenedObject
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerScreen
|
||||
fun provideGetLastSearchQuery(
|
||||
repo: UserSettingsRepository,
|
||||
dispatchers: AppCoroutineDispatchers
|
||||
): GetLastSearchQuery = GetLastSearchQuery(repo, dispatchers)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerScreen
|
||||
|
|
|
@ -135,14 +135,10 @@ class Navigator : AppNavigation {
|
|||
}
|
||||
}
|
||||
|
||||
override fun openPageSearch(initialQuery: String, space: Id) {
|
||||
// Old search
|
||||
// navController?.navigate(R.id.pageSearchFragment)
|
||||
// Uncomment to use new search
|
||||
override fun openGlobalSearch(space: Id) {
|
||||
navController?.navigate(
|
||||
R.id.globalSearchScreen,
|
||||
GlobalSearchFragment.args(
|
||||
initialQuery = initialQuery,
|
||||
resId = R.id.globalSearchScreen,
|
||||
args = GlobalSearchFragment.args(
|
||||
space = space
|
||||
)
|
||||
)
|
||||
|
|
|
@ -38,8 +38,7 @@ class NavigationRouter(
|
|||
)
|
||||
is AppNavigation.Command.Exit -> navigation.exit()
|
||||
is AppNavigation.Command.ExitToDesktop -> navigation.exitToDesktop()
|
||||
is AppNavigation.Command.OpenPageSearch -> navigation.openPageSearch(
|
||||
initialQuery = command.initialQuery,
|
||||
is AppNavigation.Command.OpenGlobalSearch -> navigation.openGlobalSearch(
|
||||
space = command.space
|
||||
)
|
||||
is AppNavigation.Command.OpenUpdateAppScreen -> navigation.openUpdateAppScreen()
|
||||
|
|
|
@ -312,8 +312,7 @@ class HomeScreenFragment : BaseComposeFragment() {
|
|||
}
|
||||
is Command.OpenGlobalSearchScreen -> {
|
||||
runCatching {
|
||||
navigation().openPageSearch(
|
||||
initialQuery = command.initialQuery,
|
||||
navigation().openGlobalSearch(
|
||||
space = command.space
|
||||
)
|
||||
}.onFailure {
|
||||
|
|
|
@ -37,7 +37,6 @@ class GlobalSearchFragment : BaseBottomSheetComposeFragment() {
|
|||
|
||||
private val vm by viewModels<GlobalSearchViewModel> { factory }
|
||||
|
||||
private val initialQuery get() = argString(ARG_INITIAL_STATE)
|
||||
private val space get() = argString(ARG_SPACE)
|
||||
|
||||
override fun onCreateView(
|
||||
|
@ -107,7 +106,6 @@ class GlobalSearchFragment : BaseBottomSheetComposeFragment() {
|
|||
|
||||
override fun injectDependencies() {
|
||||
val params = GlobalSearchViewModel.VmParams(
|
||||
initialQuery = initialQuery,
|
||||
space = SpaceId(space)
|
||||
)
|
||||
componentManager().globalSearchComponent.get(params).inject(this)
|
||||
|
@ -120,9 +118,7 @@ class GlobalSearchFragment : BaseBottomSheetComposeFragment() {
|
|||
companion object {
|
||||
const val KEYBOARD_HIDE_DELAY = 300L
|
||||
|
||||
const val ARG_INITIAL_STATE = "arg.global.search.initial_state"
|
||||
const val ARG_SPACE = "arg.global.search.space"
|
||||
fun args(initialQuery: String, space: Id): Bundle =
|
||||
bundleOf(ARG_INITIAL_STATE to initialQuery, ARG_SPACE to space)
|
||||
fun args(space: Id): Bundle = bundleOf(ARG_SPACE to space)
|
||||
}
|
||||
}
|
|
@ -27,6 +27,8 @@ import androidx.compose.foundation.lazy.LazyColumn
|
|||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.selection.LocalTextSelectionColors
|
||||
import androidx.compose.foundation.text.selection.TextSelectionColors
|
||||
import androidx.compose.material.CircularProgressIndicator
|
||||
import androidx.compose.material.DropdownMenu
|
||||
import androidx.compose.material.DropdownMenuItem
|
||||
|
@ -35,6 +37,7 @@ import androidx.compose.material.MaterialTheme
|
|||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextFieldDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
|
@ -115,6 +118,13 @@ fun GlobalSearchScreen(
|
|||
onClearRelatedClicked: () -> Unit
|
||||
) {
|
||||
|
||||
val selectionColors = TextSelectionColors(
|
||||
backgroundColor = colorResource(id = R.color.cursor_color).copy(
|
||||
alpha = 0.2f
|
||||
),
|
||||
handleColor = colorResource(id = R.color.cursor_color),
|
||||
)
|
||||
|
||||
var showLoading by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(state.isLoading) {
|
||||
|
@ -130,7 +140,17 @@ fun GlobalSearchScreen(
|
|||
var query by remember { mutableStateOf(TextFieldValue()) }
|
||||
|
||||
if (state is GlobalSearchViewModel.ViewState.Init) {
|
||||
query = TextFieldValue(text = state.query, selection = TextRange(start = 0, end = state.query.length))
|
||||
query = TextFieldValue(
|
||||
text = state.query,
|
||||
selection = TextRange(start = 0, end = state.query.length)
|
||||
)
|
||||
}
|
||||
|
||||
if (state is GlobalSearchViewModel.ViewState.RelatedInit) {
|
||||
query = TextFieldValue(
|
||||
text = state.query,
|
||||
selection = TextRange(start = 0, end = state.query.length)
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
|
@ -175,54 +195,57 @@ fun GlobalSearchScreen(
|
|||
start = 11.dp
|
||||
)
|
||||
)
|
||||
BasicTextField(
|
||||
value = query,
|
||||
modifier = Modifier
|
||||
.weight(1.0f)
|
||||
.padding(start = 6.dp)
|
||||
.align(Alignment.CenterVertically)
|
||||
.focusRequester(focusRequester)
|
||||
,
|
||||
textStyle = BodyRegular.copy(
|
||||
color = colorResource(id = R.color.text_primary)
|
||||
),
|
||||
onValueChange = { input ->
|
||||
query = input.also {
|
||||
onQueryChanged(input.text)
|
||||
}
|
||||
},
|
||||
singleLine = true,
|
||||
maxLines = 1,
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = {
|
||||
focus.clearFocus(true)
|
||||
}
|
||||
),
|
||||
decorationBox = @Composable { innerTextField ->
|
||||
TextFieldDefaults.OutlinedTextFieldDecorationBox(
|
||||
value = query.text,
|
||||
innerTextField = innerTextField,
|
||||
enabled = true,
|
||||
singleLine = true,
|
||||
visualTransformation = VisualTransformation.None,
|
||||
interactionSource = interactionSource,
|
||||
placeholder = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.search),
|
||||
style = BodyRegular.copy(
|
||||
color = colorResource(id = R.color.text_tertiary)
|
||||
CompositionLocalProvider(value = LocalTextSelectionColors provides selectionColors) {
|
||||
|
||||
BasicTextField(
|
||||
value = query,
|
||||
modifier = Modifier
|
||||
.weight(1.0f)
|
||||
.padding(start = 6.dp)
|
||||
.align(Alignment.CenterVertically)
|
||||
.focusRequester(focusRequester),
|
||||
textStyle = BodyRegular.copy(
|
||||
color = colorResource(id = R.color.text_primary)
|
||||
),
|
||||
onValueChange = { input ->
|
||||
query = input.also {
|
||||
onQueryChanged(input.text)
|
||||
}
|
||||
},
|
||||
singleLine = true,
|
||||
maxLines = 1,
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = {
|
||||
focus.clearFocus(true)
|
||||
}
|
||||
),
|
||||
decorationBox = @Composable { innerTextField ->
|
||||
TextFieldDefaults.OutlinedTextFieldDecorationBox(
|
||||
value = query.text,
|
||||
innerTextField = innerTextField,
|
||||
enabled = true,
|
||||
singleLine = true,
|
||||
visualTransformation = VisualTransformation.None,
|
||||
interactionSource = interactionSource,
|
||||
placeholder = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.search),
|
||||
style = BodyRegular.copy(
|
||||
color = colorResource(id = R.color.text_tertiary)
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
colors = TextFieldDefaults.textFieldColors(
|
||||
backgroundColor = colorResource(id = R.color.shape_transparent)
|
||||
),
|
||||
border = {},
|
||||
contentPadding = PaddingValues()
|
||||
)
|
||||
},
|
||||
cursorBrush = SolidColor(colorResource(id = R.color.palette_system_blue)),
|
||||
)
|
||||
},
|
||||
colors = TextFieldDefaults.textFieldColors(
|
||||
backgroundColor = colorResource(id = R.color.shape_transparent),
|
||||
cursorColor = colorResource(id = R.color.cursor_color),
|
||||
),
|
||||
border = {},
|
||||
contentPadding = PaddingValues()
|
||||
)
|
||||
},
|
||||
cursorBrush = SolidColor(colorResource(id = R.color.palette_system_blue)),
|
||||
)
|
||||
}
|
||||
Box(
|
||||
modifier = Modifier.size(16.dp)
|
||||
) {
|
||||
|
@ -260,55 +283,18 @@ fun GlobalSearchScreen(
|
|||
) {
|
||||
if (state is GlobalSearchViewModel.ViewState.Related) {
|
||||
stickyHeader {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.height(48.dp)
|
||||
.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.Bottom
|
||||
) {
|
||||
Text(
|
||||
text = buildAnnotatedString {
|
||||
append(stringResource(R.string.global_search_related_to))
|
||||
withStyle(
|
||||
style = SpanStyle(
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
) {
|
||||
append(state.target.title)
|
||||
}
|
||||
},
|
||||
style = Caption1Regular,
|
||||
color = colorResource(id = R.color.text_secondary),
|
||||
modifier = Modifier
|
||||
.weight(1.0f)
|
||||
.padding(
|
||||
start = 20.dp,
|
||||
bottom = 8.dp
|
||||
),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.clear),
|
||||
style = Caption1Regular,
|
||||
color = colorResource(id = R.color.text_secondary),
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
start = 20.dp,
|
||||
end = 20.dp,
|
||||
bottom = 8.dp
|
||||
)
|
||||
.clickable {
|
||||
onClearRelatedClicked().also {
|
||||
query = TextFieldValue()
|
||||
}
|
||||
}
|
||||
)
|
||||
RelatedHeader(title = state.target.title) {
|
||||
onClearRelatedClicked()
|
||||
query = TextFieldValue()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state is GlobalSearchViewModel.ViewState.RelatedInit) {
|
||||
stickyHeader {
|
||||
RelatedHeader(title = state.target.title) {
|
||||
onClearRelatedClicked()
|
||||
query = TextFieldValue()
|
||||
}
|
||||
Divider(
|
||||
paddingStart = 20.dp,
|
||||
paddingEnd = 20.dp
|
||||
)
|
||||
}
|
||||
}
|
||||
items(
|
||||
|
@ -393,6 +379,60 @@ fun GlobalSearchScreen(
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RelatedHeader(
|
||||
title: String,
|
||||
onClearRelatedClicked: () -> Unit
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.height(48.dp)
|
||||
.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.Bottom
|
||||
) {
|
||||
Text(
|
||||
text = buildAnnotatedString {
|
||||
append(stringResource(R.string.global_search_related_to))
|
||||
withStyle(
|
||||
style = SpanStyle(
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
) {
|
||||
append(title)
|
||||
}
|
||||
},
|
||||
style = Caption1Regular,
|
||||
color = colorResource(id = R.color.text_secondary),
|
||||
modifier = Modifier
|
||||
.weight(1.0f)
|
||||
.padding(
|
||||
start = 20.dp,
|
||||
bottom = 8.dp
|
||||
),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.clear),
|
||||
style = Caption1Regular,
|
||||
color = colorResource(id = R.color.text_secondary),
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
start = 20.dp,
|
||||
end = 20.dp,
|
||||
bottom = 8.dp
|
||||
)
|
||||
.clickable {
|
||||
onClearRelatedClicked()
|
||||
}
|
||||
)
|
||||
}
|
||||
Divider(
|
||||
paddingStart = 20.dp,
|
||||
paddingEnd = 20.dp
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
private fun GlobalSearchItem(
|
||||
|
@ -461,7 +501,7 @@ private fun GlobalSearchItem(
|
|||
text = globalSearchItemView.title,
|
||||
nameMeta = globalSearchItemView.nameMeta
|
||||
)
|
||||
when(val meta = globalSearchItemView.meta) {
|
||||
when (val meta = globalSearchItemView.meta) {
|
||||
is GlobalSearchItemView.Meta.Block -> {
|
||||
if (meta.highlights.isEmpty()) {
|
||||
Text(
|
||||
|
@ -476,6 +516,7 @@ private fun GlobalSearchItem(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
is GlobalSearchItemView.Meta.Default -> {
|
||||
if (meta.highlights.isEmpty()) {
|
||||
Text(
|
||||
|
@ -491,6 +532,7 @@ private fun GlobalSearchItem(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
is GlobalSearchItemView.Meta.Status -> {
|
||||
DefaultMetaStatusRelation(
|
||||
title = meta.name,
|
||||
|
@ -498,6 +540,7 @@ private fun GlobalSearchItem(
|
|||
color = meta.color
|
||||
)
|
||||
}
|
||||
|
||||
is GlobalSearchItemView.Meta.Tag -> {
|
||||
DefaultMetaTagRelation(
|
||||
title = meta.name,
|
||||
|
@ -505,6 +548,7 @@ private fun GlobalSearchItem(
|
|||
color = meta.color
|
||||
)
|
||||
}
|
||||
|
||||
is GlobalSearchItemView.Meta.None -> {
|
||||
// Draw nothing.
|
||||
}
|
||||
|
@ -715,6 +759,7 @@ fun GlobalSearchObjectIcon(
|
|||
avatarFontSize = avatarFontSize,
|
||||
avatarBackgroundColor = avatarBackgroundColor
|
||||
)
|
||||
|
||||
is ObjectIcon.Profile.Image -> DefaultProfileIconImage(icon, modifier, iconSize)
|
||||
is ObjectIcon.Basic.Emoji -> DefaultEmojiObjectIcon(modifier, iconSize, icon)
|
||||
is ObjectIcon.Basic.Image -> DefaultObjectImageIcon(icon.hash, modifier, iconSize)
|
||||
|
@ -729,6 +774,7 @@ fun GlobalSearchObjectIcon(
|
|||
iconSize = iconSize
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
// Draw nothing.
|
||||
}
|
||||
|
|
|
@ -104,8 +104,7 @@ class CollectionFragment : BaseComposeFragment() {
|
|||
space = space
|
||||
)
|
||||
is Command.ToDesktop -> navigation.exitToDesktop()
|
||||
is Command.ToSearch -> navigation.openPageSearch(
|
||||
initialQuery = command.initialQuery,
|
||||
is Command.ToSearch -> navigation.openGlobalSearch(
|
||||
space = command.space
|
||||
)
|
||||
is Command.SelectSpace -> {
|
||||
|
|
|
@ -514,14 +514,14 @@ sealed class Command {
|
|||
}
|
||||
|
||||
data class SearchWithMeta(
|
||||
val query: String,
|
||||
val limit: Int,
|
||||
val offset: Int,
|
||||
val query: String = EMPTY_QUERY,
|
||||
val limit: Int = 0,
|
||||
val offset: Int = 0,
|
||||
val keys: List<Key>,
|
||||
val sorts: List<DVSort>,
|
||||
val sorts: List<DVSort> = emptyList(),
|
||||
val filters: List<DVFilter>,
|
||||
val withMeta: Boolean,
|
||||
val withMetaRelationDetails: Boolean,
|
||||
val withMeta: Boolean = false,
|
||||
val withMetaRelationDetails: Boolean = false,
|
||||
val space: SpaceId
|
||||
) {
|
||||
data class Result(
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package com.anytypeio.anytype.core_models
|
||||
|
||||
data class GlobalSearchHistory(
|
||||
val query: String,
|
||||
val relatedObject: Id? = null
|
||||
)
|
|
@ -248,4 +248,6 @@
|
|||
|
||||
<color name="object_number_background">#F2F2F2</color>
|
||||
|
||||
<color name="object_search_cursor_color">#007AFF</color>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.anytypeio.anytype.data.auth.repo
|
||||
|
||||
import com.anytypeio.anytype.core_models.GlobalSearchHistory
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.ThemeMode
|
||||
import com.anytypeio.anytype.core_models.Wallpaper
|
||||
|
@ -22,9 +23,9 @@ interface UserSettingsCache {
|
|||
suspend fun getLastOpenedObject(space: SpaceId) : Id?
|
||||
suspend fun clearLastOpenedObject(space: SpaceId)
|
||||
|
||||
suspend fun setLastSearchQuery(query: String, space: SpaceId)
|
||||
suspend fun getLastSearchQuery(space: SpaceId): String
|
||||
suspend fun clearLastSearchQuery(space: SpaceId)
|
||||
suspend fun setGlobalSearchHistory(globalSearchHistory: GlobalSearchHistory, space: SpaceId)
|
||||
suspend fun getGlobalSearchHistory(space: SpaceId): GlobalSearchHistory?
|
||||
suspend fun clearGlobalSearchHistory(space: SpaceId)
|
||||
|
||||
suspend fun setWallpaper(space: Id, wallpaper: Wallpaper)
|
||||
suspend fun getWallpaper(space: Id) : Wallpaper
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.anytypeio.anytype.data.auth.repo
|
||||
|
||||
import com.anytypeio.anytype.core_models.GlobalSearchHistory
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.ThemeMode
|
||||
import com.anytypeio.anytype.core_models.Wallpaper
|
||||
|
@ -76,15 +77,15 @@ class UserSettingsDataRepository(private val cache: UserSettingsCache) : UserSet
|
|||
cache.clearLastOpenedObject(space)
|
||||
}
|
||||
|
||||
override suspend fun setLastSearchQuery(query: String, space: SpaceId) {
|
||||
cache.setLastSearchQuery(query, space)
|
||||
override suspend fun setGlobalSearchHistory(globalSearchHistory: GlobalSearchHistory, space: SpaceId) {
|
||||
cache.setGlobalSearchHistory(globalSearchHistory, space)
|
||||
}
|
||||
|
||||
override suspend fun getLastSearchQuery(space: SpaceId): String {
|
||||
return cache.getLastSearchQuery(space)
|
||||
override suspend fun setGlobalSearchHistory(space: SpaceId): GlobalSearchHistory? {
|
||||
return cache.getGlobalSearchHistory(space)
|
||||
}
|
||||
|
||||
override suspend fun clearLastSearchQuery(space: SpaceId) {
|
||||
cache.clearLastSearchQuery(space)
|
||||
override suspend fun clearGlobalSearchHistory(space: SpaceId) {
|
||||
cache.clearGlobalSearchHistory(space)
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.anytypeio.anytype.domain.config
|
||||
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.GlobalSearchHistory
|
||||
import com.anytypeio.anytype.core_models.ThemeMode
|
||||
import com.anytypeio.anytype.core_models.Wallpaper
|
||||
import com.anytypeio.anytype.core_models.WidgetSession
|
||||
|
@ -28,9 +29,9 @@ interface UserSettingsRepository {
|
|||
suspend fun getLastOpenedObject(space: SpaceId) : Id?
|
||||
suspend fun clearLastOpenedObject(space: SpaceId)
|
||||
|
||||
suspend fun setLastSearchQuery(query: String, space: SpaceId)
|
||||
suspend fun getLastSearchQuery(space: SpaceId): String
|
||||
suspend fun clearLastSearchQuery(space: SpaceId)
|
||||
suspend fun setGlobalSearchHistory(globalSearchHistory: GlobalSearchHistory, space: SpaceId)
|
||||
suspend fun setGlobalSearchHistory(space: SpaceId): GlobalSearchHistory?
|
||||
suspend fun clearGlobalSearchHistory(space: SpaceId)
|
||||
|
||||
suspend fun setThemeMode(mode: ThemeMode)
|
||||
suspend fun getThemeMode(): ThemeMode
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
package com.anytypeio.anytype.domain.search
|
||||
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.base.ResultInteractor
|
||||
import com.anytypeio.anytype.domain.config.UserSettingsRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class GetLastSearchQuery @Inject constructor(
|
||||
private val settings: UserSettingsRepository,
|
||||
dispatchers: AppCoroutineDispatchers
|
||||
) : ResultInteractor<GetLastSearchQuery.Params, String>(dispatchers.io) {
|
||||
|
||||
override suspend fun doWork(params: Params): String {
|
||||
return settings.getLastSearchQuery(space = params.space)
|
||||
}
|
||||
|
||||
data class Params(val space: SpaceId)
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.anytypeio.anytype.domain.search
|
||||
|
||||
import com.anytypeio.anytype.core_models.GlobalSearchHistory
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.base.ResultInteractor
|
||||
import com.anytypeio.anytype.domain.config.UserSettingsRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class RestoreGlobalSearchHistory @Inject constructor(
|
||||
private val settings: UserSettingsRepository,
|
||||
dispatchers: AppCoroutineDispatchers
|
||||
) : ResultInteractor<RestoreGlobalSearchHistory.Params, RestoreGlobalSearchHistory.Response>(
|
||||
dispatchers.io
|
||||
) {
|
||||
|
||||
override suspend fun doWork(params: Params): Response {
|
||||
return Response(
|
||||
globalSearchHistory = settings.setGlobalSearchHistory(
|
||||
space = params.spaceId
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
data class Params(
|
||||
val spaceId: SpaceId
|
||||
)
|
||||
|
||||
data class Response(
|
||||
val globalSearchHistory: GlobalSearchHistory?
|
||||
)
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package com.anytypeio.anytype.domain.search
|
||||
|
||||
import com.anytypeio.anytype.core_models.Command
|
||||
import com.anytypeio.anytype.core_models.GlobalSearchHistory
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.base.ResultInteractor
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
|
@ -9,12 +11,26 @@ import javax.inject.Inject
|
|||
|
||||
class SearchWithMeta @Inject constructor(
|
||||
private val repo: BlockRepository,
|
||||
private val dispatchers: AppCoroutineDispatchers,
|
||||
private val settings: UserSettingsRepository
|
||||
) : ResultInteractor<Command.SearchWithMeta, List<Command.SearchWithMeta.Result>>(dispatchers.io) {
|
||||
override suspend fun doWork(params: Command.SearchWithMeta): List<Command.SearchWithMeta.Result> {
|
||||
return repo.searchObjectWithMeta(command = params).also {
|
||||
settings.setLastSearchQuery(query = params.query, space = params.space)
|
||||
private val settings: UserSettingsRepository,
|
||||
dispatchers: AppCoroutineDispatchers
|
||||
) : ResultInteractor<SearchWithMeta.Params, List<Command.SearchWithMeta.Result>>(dispatchers.io) {
|
||||
override suspend fun doWork(params: SearchWithMeta.Params): List<Command.SearchWithMeta.Result> {
|
||||
return repo.searchObjectWithMeta(command = params.command).also {
|
||||
if (params.saveSearch) saveSearch(params)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun saveSearch(params: Params) {
|
||||
val search = GlobalSearchHistory(
|
||||
query = params.command.query,
|
||||
relatedObject = params.relatedObjectId
|
||||
)
|
||||
settings.setGlobalSearchHistory(globalSearchHistory = search, space = params.command.space)
|
||||
}
|
||||
|
||||
data class Params(
|
||||
val command: Command.SearchWithMeta,
|
||||
val relatedObjectId: Id?,
|
||||
val saveSearch: Boolean = false
|
||||
)
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.anytypeio.anytype.domain.search
|
||||
|
||||
import com.anytypeio.anytype.core_models.GlobalSearchHistory
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.base.ResultInteractor
|
||||
import com.anytypeio.anytype.domain.config.UserSettingsRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class UpdateGlobalSearchHistory @Inject constructor(
|
||||
private val settings: UserSettingsRepository,
|
||||
dispatchers: AppCoroutineDispatchers
|
||||
) : ResultInteractor<UpdateGlobalSearchHistory.Params, Unit>(dispatchers.io) {
|
||||
|
||||
override suspend fun doWork(params: Params) {
|
||||
settings.setGlobalSearchHistory(
|
||||
globalSearchHistory = GlobalSearchHistory(
|
||||
query = params.query,
|
||||
relatedObject = params.relatedObjectId
|
||||
),
|
||||
space = params.spaceId
|
||||
)
|
||||
}
|
||||
|
||||
data class Params(
|
||||
val spaceId: SpaceId,
|
||||
val query: String,
|
||||
val relatedObjectId: Id?
|
||||
)
|
||||
}
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||
import android.content.SharedPreferences
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.dataStore
|
||||
import com.anytypeio.anytype.core_models.GlobalSearchHistory
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.NO_VALUE
|
||||
import com.anytypeio.anytype.core_models.ThemeMode
|
||||
|
@ -12,6 +13,7 @@ import com.anytypeio.anytype.core_models.WidgetSession
|
|||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.core_models.primitives.TypeId
|
||||
import com.anytypeio.anytype.data.auth.repo.UserSettingsCache
|
||||
import com.anytypeio.anytype.persistence.GlobalSearchHistoryProto
|
||||
import com.anytypeio.anytype.persistence.SpacePreference
|
||||
import com.anytypeio.anytype.persistence.SpacePreferences
|
||||
import com.anytypeio.anytype.persistence.common.JsonString
|
||||
|
@ -318,7 +320,7 @@ class DefaultUserSettingsCache(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun setLastSearchQuery(query: String, space: SpaceId) {
|
||||
override suspend fun setGlobalSearchHistory(globalSearchHistory: GlobalSearchHistory, space: SpaceId) {
|
||||
context.spacePrefsStore.updateData { existingPreferences ->
|
||||
val givenSpacePreference = existingPreferences
|
||||
.preferences
|
||||
|
@ -327,7 +329,10 @@ class DefaultUserSettingsCache(
|
|||
defaultValue = SpacePreference()
|
||||
)
|
||||
val updated = givenSpacePreference.copy(
|
||||
lastSearchQuery = query
|
||||
globalSearchHistory = GlobalSearchHistoryProto(
|
||||
lastSearchQuery = globalSearchHistory.query,
|
||||
lastSearchRelatedObjectId = globalSearchHistory.relatedObject
|
||||
)
|
||||
)
|
||||
val result = buildMap {
|
||||
putAll(existingPreferences.preferences)
|
||||
|
@ -337,24 +342,33 @@ class DefaultUserSettingsCache(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun getLastSearchQuery(space: SpaceId): String {
|
||||
override suspend fun getGlobalSearchHistory(space: SpaceId): GlobalSearchHistory? {
|
||||
return context.spacePrefsStore
|
||||
.data
|
||||
.map { preferences ->
|
||||
preferences
|
||||
val result = preferences
|
||||
.preferences[space.id]
|
||||
?.lastSearchQuery.orEmpty()
|
||||
?.globalSearchHistory
|
||||
|
||||
if (result == null) {
|
||||
return@map null
|
||||
} else {
|
||||
GlobalSearchHistory(
|
||||
query = result.lastSearchQuery.orEmpty(),
|
||||
relatedObject = result.lastSearchRelatedObjectId
|
||||
)
|
||||
}
|
||||
}
|
||||
.first()
|
||||
}
|
||||
|
||||
override suspend fun clearLastSearchQuery(space: SpaceId) {
|
||||
override suspend fun clearGlobalSearchHistory(space: SpaceId) {
|
||||
context.spacePrefsStore.updateData { existingPreferences ->
|
||||
val givenSpacePreference = existingPreferences
|
||||
.preferences
|
||||
.getOrDefault(key = space.id, defaultValue = SpacePreference())
|
||||
val updated = givenSpacePreference.copy(
|
||||
lastSearchQuery = null
|
||||
globalSearchHistory = null
|
||||
)
|
||||
val result = buildMap {
|
||||
putAll(existingPreferences.preferences)
|
||||
|
|
|
@ -12,5 +12,10 @@ message SpacePreference {
|
|||
optional string defaultObjectTypeKey = 1;
|
||||
repeated string pinnedObjectTypeIds = 2;
|
||||
optional string lastOpenedObject = 3;
|
||||
optional string lastSearchQuery = 4;
|
||||
optional GlobalSearchHistoryProto globalSearchHistory = 5;
|
||||
}
|
||||
|
||||
message GlobalSearchHistoryProto {
|
||||
optional string lastSearchQuery = 1;
|
||||
optional string lastSearchRelatedObjectId = 2;
|
||||
}
|
|
@ -3,6 +3,7 @@ package com.anytypeio.anytype.persistence
|
|||
import android.content.Context
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.anytypeio.anytype.core_models.GlobalSearchHistory
|
||||
import com.anytypeio.anytype.core_models.Wallpaper
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.core_models.primitives.TypeId
|
||||
|
@ -270,4 +271,47 @@ class UserSettingsCacheTest {
|
|||
actual = cache.getDefaultObjectType(space2)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should save global search for given space and then clear it`() = runTest {
|
||||
|
||||
val cache = DefaultUserSettingsCache(
|
||||
prefs = defaultPrefs,
|
||||
context = ApplicationProvider.getApplicationContext()
|
||||
)
|
||||
|
||||
val space = SpaceId(MockDataFactory.randomUuid())
|
||||
val globalSearch = GlobalSearchHistory(
|
||||
query = MockDataFactory.randomString(),
|
||||
relatedObject = MockDataFactory.randomUuid()
|
||||
)
|
||||
|
||||
// Settings are empty before we save anything
|
||||
|
||||
assertEquals(
|
||||
expected = null,
|
||||
actual = cache.getDefaultObjectType(space)
|
||||
)
|
||||
|
||||
// Saving global search for given space
|
||||
|
||||
cache.setGlobalSearchHistory(
|
||||
globalSearchHistory = globalSearch,
|
||||
space = space
|
||||
)
|
||||
|
||||
// Making sure global search is saved
|
||||
|
||||
assertEquals(
|
||||
expected = globalSearch,
|
||||
actual = cache.getGlobalSearchHistory(space)
|
||||
)
|
||||
|
||||
cache.clearGlobalSearchHistory(space)
|
||||
|
||||
assertEquals(
|
||||
expected = null,
|
||||
actual = cache.getGlobalSearchHistory(space)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -98,7 +98,6 @@ import com.anytypeio.anytype.domain.page.CreateObject
|
|||
import com.anytypeio.anytype.domain.page.CreateObjectAsMentionOrLink
|
||||
import com.anytypeio.anytype.domain.page.OpenPage
|
||||
import com.anytypeio.anytype.domain.relations.AddRelationToObject
|
||||
import com.anytypeio.anytype.domain.search.GetLastSearchQuery
|
||||
import com.anytypeio.anytype.domain.search.SearchObjects
|
||||
import com.anytypeio.anytype.domain.sets.FindObjectSetForType
|
||||
import com.anytypeio.anytype.domain.templates.ApplyTemplate
|
||||
|
@ -332,8 +331,7 @@ class EditorViewModel(
|
|||
private val getNetworkMode: GetNetworkMode,
|
||||
private val clearLastOpenedObject: ClearLastOpenedObject,
|
||||
private val analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate,
|
||||
private val spaceSyncAndP2PStatusProvider: SpaceSyncAndP2PStatusProvider,
|
||||
private val getLastSearchQuery: GetLastSearchQuery
|
||||
private val spaceSyncAndP2PStatusProvider: SpaceSyncAndP2PStatusProvider
|
||||
) : ViewStateViewModel<ViewState>(),
|
||||
PickerListener,
|
||||
SupportNavigation<EventWrapper<AppNavigation.Command>>,
|
||||
|
@ -4305,29 +4303,12 @@ class EditorViewModel(
|
|||
)
|
||||
|
||||
viewModelScope.launch {
|
||||
val params = GetLastSearchQuery.Params(space = vmParams.space)
|
||||
getLastSearchQuery.async(params).fold(
|
||||
onSuccess = { query ->
|
||||
navigation.postValue(
|
||||
EventWrapper(
|
||||
AppNavigation.Command.OpenPageSearch(
|
||||
initialQuery = query,
|
||||
space = vmParams.space.id
|
||||
)
|
||||
)
|
||||
navigation.postValue(
|
||||
EventWrapper(
|
||||
AppNavigation.Command.OpenGlobalSearch(
|
||||
space = vmParams.space.id
|
||||
)
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "Error while getting last search query")
|
||||
navigation.postValue(
|
||||
EventWrapper(
|
||||
AppNavigation.Command.OpenPageSearch(
|
||||
initialQuery = "",
|
||||
space = vmParams.space.id
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ import com.anytypeio.anytype.domain.page.CreateObject
|
|||
import com.anytypeio.anytype.domain.page.CreateObjectAsMentionOrLink
|
||||
import com.anytypeio.anytype.domain.page.OpenPage
|
||||
import com.anytypeio.anytype.domain.relations.AddRelationToObject
|
||||
import com.anytypeio.anytype.domain.search.GetLastSearchQuery
|
||||
import com.anytypeio.anytype.domain.search.SearchObjects
|
||||
import com.anytypeio.anytype.domain.sets.FindObjectSetForType
|
||||
import com.anytypeio.anytype.domain.templates.ApplyTemplate
|
||||
|
@ -98,8 +97,7 @@ open class EditorViewModelFactory @Inject constructor(
|
|||
private val getNetworkMode: GetNetworkMode,
|
||||
private val clearLastOpenedObject: ClearLastOpenedObject,
|
||||
private val analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate,
|
||||
private val syncStatusProvider: SpaceSyncAndP2PStatusProvider,
|
||||
private val getLastSearchQuery: GetLastSearchQuery
|
||||
private val syncStatusProvider: SpaceSyncAndP2PStatusProvider
|
||||
) : ViewModelProvider.Factory {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
@ -149,8 +147,7 @@ open class EditorViewModelFactory @Inject constructor(
|
|||
spaceSyncAndP2PStatusProvider = syncStatusProvider,
|
||||
getNetworkMode = getNetworkMode,
|
||||
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate,
|
||||
clearLastOpenedObject = clearLastOpenedObject,
|
||||
getLastSearchQuery = getLastSearchQuery
|
||||
clearLastOpenedObject = clearLastOpenedObject
|
||||
) as T
|
||||
}
|
||||
}
|
|
@ -58,7 +58,6 @@ 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.CreateObject
|
||||
import com.anytypeio.anytype.domain.search.GetLastSearchQuery
|
||||
import com.anytypeio.anytype.domain.search.SearchObjects
|
||||
import com.anytypeio.anytype.domain.spaces.ClearLastOpenedSpace
|
||||
import com.anytypeio.anytype.domain.spaces.GetSpaceView
|
||||
|
@ -197,7 +196,6 @@ class HomeScreenViewModel(
|
|||
private val createBlock: CreateBlock,
|
||||
private val dateProvider: DateProvider,
|
||||
private val addObjectToCollection: AddObjectToCollection,
|
||||
private val getLastSearchQuery: GetLastSearchQuery,
|
||||
private val clearLastOpenedSpace: ClearLastOpenedSpace
|
||||
) : NavigationViewModel<HomeScreenViewModel.Navigation>(),
|
||||
Reducer<ObjectView, Payload>,
|
||||
|
@ -1697,26 +1695,8 @@ class HomeScreenViewModel(
|
|||
|
||||
fun onSearchIconClicked() {
|
||||
viewModelScope.launch {
|
||||
val space = spaceManager.get()
|
||||
val params = GetLastSearchQuery.Params(space = SpaceId(space))
|
||||
getLastSearchQuery.async(params).fold(
|
||||
onSuccess = { query ->
|
||||
commands.emit(
|
||||
Command.OpenGlobalSearchScreen(
|
||||
initialQuery = query,
|
||||
space = space
|
||||
)
|
||||
)
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "Error while getting last search query")
|
||||
commands.emit(
|
||||
Command.OpenGlobalSearchScreen(
|
||||
initialQuery = "",
|
||||
space = space
|
||||
)
|
||||
)
|
||||
}
|
||||
commands.emit(
|
||||
Command.OpenGlobalSearchScreen(space = spaceManager.get())
|
||||
)
|
||||
}
|
||||
viewModelScope.sendEvent(
|
||||
|
@ -2097,7 +2077,6 @@ class HomeScreenViewModel(
|
|||
private val dateProvider: DateProvider,
|
||||
private val coverImageHashProvider: CoverImageHashProvider,
|
||||
private val addObjectToCollection: AddObjectToCollection,
|
||||
private val getLastSearchQuery: GetLastSearchQuery,
|
||||
private val clearLastOpenedSpace: ClearLastOpenedSpace
|
||||
) : ViewModelProvider.Factory {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
@ -2146,7 +2125,6 @@ class HomeScreenViewModel(
|
|||
createBlock = createBlock,
|
||||
dateProvider = dateProvider,
|
||||
addObjectToCollection = addObjectToCollection,
|
||||
getLastSearchQuery = getLastSearchQuery,
|
||||
clearLastOpenedSpace = clearLastOpenedSpace
|
||||
) as T
|
||||
}
|
||||
|
@ -2190,7 +2168,7 @@ sealed class Command {
|
|||
|
||||
data class OpenObjectCreateDialog(val space: SpaceId) : Command()
|
||||
|
||||
data class OpenGlobalSearchScreen(val initialQuery: String, val space: Id) : Command()
|
||||
data class OpenGlobalSearchScreen(val space: Id) : Command()
|
||||
|
||||
data object OpenVault: Command()
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ interface AppNavigation {
|
|||
|
||||
fun exit()
|
||||
fun exitToDesktop()
|
||||
fun openPageSearch(initialQuery: String, space: Id)
|
||||
fun openGlobalSearch(space: Id)
|
||||
fun openUpdateAppScreen()
|
||||
fun openRemoteFilesManageScreen(subscription: Id)
|
||||
|
||||
|
@ -69,8 +69,7 @@ interface AppNavigation {
|
|||
object OpenSettings : Command()
|
||||
object MigrationErrorScreen: Command()
|
||||
|
||||
data class OpenPageSearch(
|
||||
val initialQuery: String,
|
||||
data class OpenGlobalSearch(
|
||||
val space: Id
|
||||
) : Command()
|
||||
|
||||
|
|
|
@ -30,10 +30,13 @@ import com.anytypeio.anytype.core_models.ThemeColor
|
|||
import com.anytypeio.anytype.core_models.ext.EMPTY_STRING_VALUE
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.domain.base.Resultat
|
||||
import com.anytypeio.anytype.domain.base.fold
|
||||
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.search.RestoreGlobalSearchHistory
|
||||
import com.anytypeio.anytype.domain.search.SearchWithMeta
|
||||
import com.anytypeio.anytype.domain.search.UpdateGlobalSearchHistory
|
||||
import com.anytypeio.anytype.presentation.analytics.AnalyticSpaceHelperDelegate
|
||||
import com.anytypeio.anytype.presentation.common.BaseViewModel
|
||||
import com.anytypeio.anytype.presentation.extension.sendAnalyticsSearchBacklinksEvent
|
||||
|
@ -42,10 +45,13 @@ import com.anytypeio.anytype.presentation.home.OpenObjectNavigation
|
|||
import com.anytypeio.anytype.presentation.home.navigation
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.getProperName
|
||||
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants.filterObjectsByIds
|
||||
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants.filterSearchObjects
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
|
@ -55,7 +61,6 @@ import kotlinx.coroutines.flow.flatMapLatest
|
|||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onCompletion
|
||||
import kotlinx.coroutines.flow.scan
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
@ -68,9 +73,11 @@ class GlobalSearchViewModel(
|
|||
private val urlBuilder: UrlBuilder,
|
||||
private val analytics: Analytics,
|
||||
private val analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate,
|
||||
private val restoreGlobalSearchHistory: RestoreGlobalSearchHistory,
|
||||
private val updateGlobalSearchHistory: UpdateGlobalSearchHistory
|
||||
) : BaseViewModel(), AnalyticSpaceHelperDelegate by analyticSpaceHelperDelegate {
|
||||
|
||||
private val userInput = MutableStateFlow(vmParams.initialQuery)
|
||||
private val userInput = MutableStateFlow("")
|
||||
private val searchQuery = userInput
|
||||
.take(1)
|
||||
.onCompletion {
|
||||
|
@ -81,51 +88,129 @@ class GlobalSearchViewModel(
|
|||
|
||||
val navigation = MutableSharedFlow<OpenObjectNavigation>()
|
||||
|
||||
val state = combine(
|
||||
mode,
|
||||
searchQuery
|
||||
) { mode, query ->
|
||||
mode to query
|
||||
}.flatMapLatest { (mode, query) ->
|
||||
when(mode) {
|
||||
is Mode.Default -> {
|
||||
buildDefaultSearchFlow(query = query, space = vmParams.space)
|
||||
}
|
||||
is Mode.Related -> {
|
||||
buildRelatedSearchFlow(query = query, mode = mode, space = vmParams.space)
|
||||
}
|
||||
private val _state: MutableStateFlow<ViewState> = MutableStateFlow(ViewState.Init())
|
||||
val state = _state.asStateFlow()
|
||||
|
||||
init {
|
||||
Timber.d("GlobalSearchViewModel, init")
|
||||
proceedRestoreGlobalSearch(space = vmParams.space)
|
||||
}
|
||||
|
||||
private fun proceedRestoreGlobalSearch(space: SpaceId) {
|
||||
Timber.d("restoreGlobalSearch, space $space")
|
||||
viewModelScope.launch {
|
||||
val params = RestoreGlobalSearchHistory.Params(spaceId = space)
|
||||
restoreGlobalSearchHistory.async(params = params).fold(
|
||||
onSuccess = { response ->
|
||||
val globalSearchHistory = response.globalSearchHistory
|
||||
Timber.d("restoreGlobalSearchHistory, onSuccess $globalSearchHistory")
|
||||
userInput.value = globalSearchHistory?.query ?: EMPTY_STRING_VALUE
|
||||
val relatedObjectId = globalSearchHistory?.relatedObject
|
||||
if (!relatedObjectId.isNullOrEmpty()) {
|
||||
proceedRelatedObjectSearch(
|
||||
query = globalSearchHistory.query,
|
||||
relatedObjectId = relatedObjectId
|
||||
)
|
||||
} else {
|
||||
val initialState =
|
||||
ViewState.Init(query = globalSearchHistory?.query ?: EMPTY_STRING_VALUE)
|
||||
proceedWithInitialState(initialState)
|
||||
}
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "restoreGlobalSearch, onFailure")
|
||||
userInput.value = EMPTY_STRING_VALUE
|
||||
proceedWithInitialState(ViewState.Init(query = EMPTY_STRING_VALUE))
|
||||
}
|
||||
)
|
||||
}
|
||||
}.scan<ViewState, ViewState>(
|
||||
initial = ViewState.Init(
|
||||
query = vmParams.initialQuery
|
||||
}
|
||||
|
||||
private suspend fun proceedRelatedObjectSearch(query: String, relatedObjectId: Id) {
|
||||
val params = SearchWithMeta.Params(
|
||||
relatedObjectId = relatedObjectId,
|
||||
command = Command.SearchWithMeta(
|
||||
limit = 1,
|
||||
keys = DEFAULT_KEYS,
|
||||
filters = filterObjectsByIds(
|
||||
ids = listOf(relatedObjectId),
|
||||
spaces = listOf(vmParams.space.id)
|
||||
),
|
||||
space = vmParams.space
|
||||
)
|
||||
)
|
||||
) { curr, new ->
|
||||
when(new) {
|
||||
is ViewState.Default -> {
|
||||
if (new.isLoading) {
|
||||
new.copy(
|
||||
views = curr.views
|
||||
searchWithMeta.async(params).fold(
|
||||
onSuccess = { result ->
|
||||
Timber.d("proceedRelatedObjectSearch, onSuccess $result")
|
||||
val relatedGlobalSearchItemView = result.firstOrNull()?.view(
|
||||
storeOfRelations = storeOfRelations,
|
||||
storeOfObjectTypes = storeOfObjectTypes,
|
||||
urlBuilder = urlBuilder
|
||||
)
|
||||
if (relatedGlobalSearchItemView != null) {
|
||||
mode.value = Mode.Related(target = relatedGlobalSearchItemView)
|
||||
proceedWithInitialState(
|
||||
ViewState.RelatedInit(
|
||||
query = query,
|
||||
target = relatedGlobalSearchItemView,
|
||||
isLoading = false
|
||||
)
|
||||
)
|
||||
} else {
|
||||
new
|
||||
proceedWithInitialState(ViewState.Init(query = query))
|
||||
}
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "proceedRelatedObjectSearch, onFailure")
|
||||
proceedWithInitialState(ViewState.Init(query = query))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private suspend fun proceedWithInitialState(initial: ViewState) {
|
||||
combine(
|
||||
mode,
|
||||
searchQuery
|
||||
) { mode, query ->
|
||||
mode to query
|
||||
}.flatMapLatest { (mode, query) ->
|
||||
when(mode) {
|
||||
is Mode.Default -> {
|
||||
buildDefaultSearchFlow(query = query, space = vmParams.space)
|
||||
}
|
||||
is Mode.Related -> {
|
||||
buildRelatedSearchFlow(query = query, mode = mode, space = vmParams.space)
|
||||
}
|
||||
}
|
||||
is ViewState.Related -> {
|
||||
if (new.isLoading) {
|
||||
new.copy(
|
||||
views = curr.views
|
||||
)
|
||||
} else {
|
||||
new
|
||||
}.scan(
|
||||
initial = initial
|
||||
) { curr, new ->
|
||||
when(new) {
|
||||
is ViewState.Default -> {
|
||||
if (new.isLoading) {
|
||||
new.copy(
|
||||
views = curr.views
|
||||
)
|
||||
} else {
|
||||
new
|
||||
}
|
||||
}
|
||||
is ViewState.Related -> {
|
||||
if (new.isLoading) {
|
||||
new.copy(
|
||||
views = curr.views
|
||||
)
|
||||
} else {
|
||||
new
|
||||
}
|
||||
}
|
||||
else -> new
|
||||
}
|
||||
else -> new
|
||||
}.collect {
|
||||
_state.value = it
|
||||
}
|
||||
}.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.WhileSubscribed(),
|
||||
initialValue = ViewState.Init("")
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun buildRelatedSearchFlow(
|
||||
query: String,
|
||||
|
@ -133,32 +218,12 @@ class GlobalSearchViewModel(
|
|||
space: SpaceId
|
||||
) = searchWithMeta
|
||||
.stream(
|
||||
Command.SearchWithMeta(
|
||||
relatedSearchFlowParams(
|
||||
query = query,
|
||||
limit = DEFAULT_SEARCH_LIMIT,
|
||||
offset = 0,
|
||||
keys = DEFAULT_KEYS,
|
||||
filters = buildList {
|
||||
addAll(
|
||||
ObjectSearchConstants.filterSearchObjects(
|
||||
spaces = listOf(vmParams.space.id)
|
||||
)
|
||||
)
|
||||
add(
|
||||
DVFilter(
|
||||
relation = Relations.ID,
|
||||
value = buildSet {
|
||||
addAll(mode.target.links)
|
||||
addAll(mode.target.backlinks)
|
||||
}.toList(),
|
||||
condition = DVFilterCondition.IN
|
||||
)
|
||||
)
|
||||
},
|
||||
sorts = ObjectSearchConstants.sortsSearchObjects,
|
||||
withMetaRelationDetails = false,
|
||||
withMeta = false,
|
||||
space = space
|
||||
links = mode.target.links,
|
||||
backlinks = mode.target.backlinks,
|
||||
space = space,
|
||||
relatedObjectId = mode.target.id
|
||||
)
|
||||
).map { result ->
|
||||
when (result) {
|
||||
|
@ -191,22 +256,67 @@ class GlobalSearchViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun buildDefaultSearchFlow(query: String, space: SpaceId) = searchWithMeta
|
||||
.stream(
|
||||
Command.SearchWithMeta(
|
||||
private fun relatedSearchFlowParams(
|
||||
query: String,
|
||||
links: List<Id>,
|
||||
backlinks: List<Id>,
|
||||
space: SpaceId,
|
||||
relatedObjectId: Id?
|
||||
): SearchWithMeta.Params {
|
||||
return SearchWithMeta.Params(
|
||||
saveSearch = true,
|
||||
relatedObjectId = relatedObjectId,
|
||||
command = Command.SearchWithMeta(
|
||||
query = query,
|
||||
limit = DEFAULT_SEARCH_LIMIT,
|
||||
offset = 0,
|
||||
keys = DEFAULT_KEYS,
|
||||
filters = ObjectSearchConstants.filterSearchObjects(
|
||||
// TODO add tech space?
|
||||
spaces = listOf(space.id)
|
||||
),
|
||||
filters = buildList {
|
||||
addAll(
|
||||
filterSearchObjects(
|
||||
spaces = listOf(vmParams.space.id)
|
||||
)
|
||||
)
|
||||
add(
|
||||
DVFilter(
|
||||
relation = Relations.ID,
|
||||
value = buildSet {
|
||||
addAll(links)
|
||||
addAll(backlinks)
|
||||
}.toList(),
|
||||
condition = DVFilterCondition.IN
|
||||
)
|
||||
)
|
||||
},
|
||||
sorts = ObjectSearchConstants.sortsSearchObjects,
|
||||
withMetaRelationDetails = true,
|
||||
withMeta = true,
|
||||
withMetaRelationDetails = false,
|
||||
withMeta = false,
|
||||
space = space
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun buildDefaultSearchFlow(query: String, space: SpaceId) = searchWithMeta
|
||||
.stream(
|
||||
SearchWithMeta.Params(
|
||||
saveSearch = true,
|
||||
relatedObjectId = null,
|
||||
command = Command.SearchWithMeta(
|
||||
query = query,
|
||||
limit = DEFAULT_SEARCH_LIMIT,
|
||||
offset = 0,
|
||||
keys = DEFAULT_KEYS,
|
||||
filters = ObjectSearchConstants.filterSearchObjects(
|
||||
// TODO add tech space?
|
||||
spaces = listOf(space.id)
|
||||
),
|
||||
sorts = ObjectSearchConstants.sortsSearchObjects,
|
||||
withMetaRelationDetails = true,
|
||||
withMeta = true,
|
||||
space = space
|
||||
)
|
||||
)
|
||||
|
||||
).map { result ->
|
||||
when (result) {
|
||||
is Resultat.Failure -> {
|
||||
|
@ -272,6 +382,10 @@ class GlobalSearchViewModel(
|
|||
viewModelScope.launch {
|
||||
userInput.value = EMPTY_STRING_VALUE
|
||||
mode.value = Mode.Related(globalSearchItemView)
|
||||
proceedUpdateGlobalSearch(
|
||||
query = EMPTY_STRING_VALUE,
|
||||
relatedObjectId = globalSearchItemView.id
|
||||
)
|
||||
}
|
||||
viewModelScope.launch {
|
||||
sendAnalyticsSearchBacklinksEvent(
|
||||
|
@ -281,7 +395,23 @@ class GlobalSearchViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
data class VmParams(val initialQuery: String, val space: SpaceId)
|
||||
private suspend fun proceedUpdateGlobalSearch(query: String, relatedObjectId: Id?) {
|
||||
val params = UpdateGlobalSearchHistory.Params(
|
||||
spaceId = vmParams.space,
|
||||
query = query,
|
||||
relatedObjectId = relatedObjectId
|
||||
)
|
||||
updateGlobalSearchHistory.async(params).fold(
|
||||
onSuccess = {
|
||||
Timber.i("updateGlobalSearch, onSuccess")
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "updateGlobalSearch, onFailure")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
data class VmParams(val space: SpaceId)
|
||||
|
||||
class Factory @Inject constructor(
|
||||
private val vmParams: VmParams,
|
||||
|
@ -290,7 +420,9 @@ class GlobalSearchViewModel(
|
|||
private val storeOfRelations: StoreOfRelations,
|
||||
private val urlBuilder: UrlBuilder,
|
||||
private val analytics: Analytics,
|
||||
private val analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate
|
||||
private val analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate,
|
||||
private val restoreGlobalSearchHistory: RestoreGlobalSearchHistory,
|
||||
private val updateGlobalSearchHistory: UpdateGlobalSearchHistory
|
||||
) : ViewModelProvider.Factory {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
|
@ -301,7 +433,9 @@ class GlobalSearchViewModel(
|
|||
storeOfRelations = storeOfRelations,
|
||||
urlBuilder = urlBuilder,
|
||||
analytics = analytics,
|
||||
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate
|
||||
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate,
|
||||
restoreGlobalSearchHistory = restoreGlobalSearchHistory,
|
||||
updateGlobalSearchHistory = updateGlobalSearchHistory
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
@ -343,6 +477,14 @@ class GlobalSearchViewModel(
|
|||
override val isLoading: Boolean
|
||||
): ViewState()
|
||||
|
||||
//ToDo: remove this state, and make Related sealed class
|
||||
data class RelatedInit (
|
||||
val query: String = EMPTY_STRING_VALUE,
|
||||
val target: GlobalSearchItemView,
|
||||
override val views: List<GlobalSearchItemView> = emptyList(),
|
||||
override val isLoading: Boolean
|
||||
): ViewState()
|
||||
|
||||
fun isEmptyState() : Boolean {
|
||||
return this !is Init && !this.isLoading && views.isEmpty()
|
||||
}
|
||||
|
|
|
@ -649,7 +649,9 @@ object ObjectSearchConstants {
|
|||
Relations.RESTRICTIONS,
|
||||
Relations.SIZE_IN_BYTES,
|
||||
Relations.FILE_MIME_TYPE,
|
||||
Relations.FILE_EXT
|
||||
Relations.FILE_EXT,
|
||||
Relations.LAST_OPENED_DATE,
|
||||
Relations.LAST_MODIFIED_DATE
|
||||
)
|
||||
|
||||
val defaultOptionKeys = listOf(
|
||||
|
|
|
@ -57,7 +57,6 @@ import com.anytypeio.anytype.domain.page.CloseBlock
|
|||
import com.anytypeio.anytype.domain.page.CreateObject
|
||||
import com.anytypeio.anytype.domain.search.DataViewState
|
||||
import com.anytypeio.anytype.domain.search.DataViewSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.search.GetLastSearchQuery
|
||||
import com.anytypeio.anytype.domain.sets.OpenObjectSet
|
||||
import com.anytypeio.anytype.domain.sets.SetQueryToObjectSet
|
||||
import com.anytypeio.anytype.domain.templates.CreateTemplate
|
||||
|
@ -181,7 +180,6 @@ class ObjectSetViewModel(
|
|||
private val analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate,
|
||||
private val spaceSyncAndP2PStatusProvider: SpaceSyncAndP2PStatusProvider,
|
||||
private val clearLastOpenedObject: ClearLastOpenedObject,
|
||||
private val getLastSearchQuery: GetLastSearchQuery
|
||||
) : ViewModel(), SupportNavigation<EventWrapper<AppNavigation.Command>>,
|
||||
ViewerDelegate by viewerDelegate,
|
||||
AnalyticSpaceHelperDelegate by analyticSpaceHelperDelegate
|
||||
|
@ -1655,25 +1653,10 @@ class ObjectSetViewModel(
|
|||
props = Props(mapOf(EventsPropertiesKey.route to EventsDictionary.Routes.navigation))
|
||||
)
|
||||
viewModelScope.launch {
|
||||
val params = GetLastSearchQuery.Params(space = vmParams.space)
|
||||
getLastSearchQuery.async(params).fold(
|
||||
onSuccess = { query ->
|
||||
dispatch(
|
||||
AppNavigation.Command.OpenPageSearch(
|
||||
initialQuery = query,
|
||||
space = vmParams.space.id
|
||||
)
|
||||
)
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "Error while getting last search query")
|
||||
dispatch(
|
||||
AppNavigation.Command.OpenPageSearch(
|
||||
initialQuery = "",
|
||||
space = vmParams.space.id
|
||||
)
|
||||
)
|
||||
}
|
||||
dispatch(
|
||||
AppNavigation.Command.OpenGlobalSearch(
|
||||
space = vmParams.space.id
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import com.anytypeio.anytype.domain.objects.StoreOfRelations
|
|||
import com.anytypeio.anytype.domain.page.CloseBlock
|
||||
import com.anytypeio.anytype.domain.page.CreateObject
|
||||
import com.anytypeio.anytype.domain.search.DataViewSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.search.GetLastSearchQuery
|
||||
import com.anytypeio.anytype.domain.sets.OpenObjectSet
|
||||
import com.anytypeio.anytype.domain.sets.SetQueryToObjectSet
|
||||
import com.anytypeio.anytype.domain.templates.CreateTemplate
|
||||
|
@ -84,8 +83,7 @@ class ObjectSetViewModelFactory(
|
|||
private val dateProvider: DateProvider,
|
||||
private val spaceSyncAndP2PStatusProvider: SpaceSyncAndP2PStatusProvider,
|
||||
private val analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate,
|
||||
private val clearLastOpenedObject: ClearLastOpenedObject,
|
||||
private val getLastSearchQuery: GetLastSearchQuery
|
||||
private val clearLastOpenedObject: ClearLastOpenedObject
|
||||
) : ViewModelProvider.Factory {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
|
@ -130,8 +128,7 @@ class ObjectSetViewModelFactory(
|
|||
dateProvider = dateProvider,
|
||||
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate,
|
||||
spaceSyncAndP2PStatusProvider = spaceSyncAndP2PStatusProvider,
|
||||
clearLastOpenedObject = clearLastOpenedObject,
|
||||
getLastSearchQuery = getLastSearchQuery
|
||||
clearLastOpenedObject = clearLastOpenedObject
|
||||
) as T
|
||||
}
|
||||
}
|
|
@ -16,7 +16,6 @@ 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.core_models.ext.process
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.core_utils.ext.cancel
|
||||
import com.anytypeio.anytype.core_utils.ext.replace
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
|
@ -39,7 +38,6 @@ import com.anytypeio.anytype.domain.objects.DeleteObjects
|
|||
import com.anytypeio.anytype.domain.objects.SetObjectListIsArchived
|
||||
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
|
||||
import com.anytypeio.anytype.domain.page.CreateObject
|
||||
import com.anytypeio.anytype.domain.search.GetLastSearchQuery
|
||||
import com.anytypeio.anytype.domain.spaces.GetSpaceView
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceManager
|
||||
import com.anytypeio.anytype.domain.workspace.getSpaceWithTechSpace
|
||||
|
@ -47,7 +45,6 @@ import com.anytypeio.anytype.presentation.analytics.AnalyticSpaceHelperDelegate
|
|||
import com.anytypeio.anytype.presentation.extension.sendAnalyticsObjectCreateEvent
|
||||
import com.anytypeio.anytype.presentation.extension.sendDeletionWarning
|
||||
import com.anytypeio.anytype.presentation.extension.sendScreenHomeEvent
|
||||
import com.anytypeio.anytype.presentation.home.Command
|
||||
import com.anytypeio.anytype.presentation.home.HomeScreenViewModel.Companion.HOME_SCREEN_PROFILE_OBJECT_SUBSCRIPTION
|
||||
import com.anytypeio.anytype.presentation.home.OpenObjectNavigation
|
||||
import com.anytypeio.anytype.presentation.home.navigation
|
||||
|
@ -110,8 +107,7 @@ class CollectionViewModel(
|
|||
private val spaceManager: SpaceManager,
|
||||
private val getSpaceView: GetSpaceView,
|
||||
private val dateTypeNameProvider: DateTypeNameProvider,
|
||||
private val analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate,
|
||||
private val getLastSearchQuery: GetLastSearchQuery
|
||||
private val analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate
|
||||
) : ViewModel(), Reducer<CoreObjectView, Payload>, AnalyticSpaceHelperDelegate by analyticSpaceHelperDelegate {
|
||||
|
||||
val payloads: Flow<Payload>
|
||||
|
@ -834,25 +830,8 @@ class CollectionViewModel(
|
|||
props = Props(mapOf(EventsPropertiesKey.route to EventsDictionary.Routes.navigation))
|
||||
)
|
||||
viewModelScope.launch {
|
||||
val params = GetLastSearchQuery.Params(space = SpaceId(space))
|
||||
getLastSearchQuery.async(params).fold(
|
||||
onSuccess = { query ->
|
||||
commands.emit(
|
||||
Command.ToSearch(
|
||||
initialQuery = query,
|
||||
space = space
|
||||
)
|
||||
)
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "Error while getting last search query")
|
||||
commands.emit(
|
||||
Command.ToSearch(
|
||||
initialQuery = "",
|
||||
space = space
|
||||
)
|
||||
)
|
||||
}
|
||||
commands.emit(
|
||||
Command.ToSearch(space = space)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -967,8 +946,7 @@ class CollectionViewModel(
|
|||
private val spaceManager: SpaceManager,
|
||||
private val getSpaceView: GetSpaceView,
|
||||
private val dateTypeNameProvider: DateTypeNameProvider,
|
||||
private val analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate,
|
||||
private val getLastSearchQuery: GetLastSearchQuery
|
||||
private val analyticSpaceHelperDelegate: AnalyticSpaceHelperDelegate
|
||||
) : ViewModelProvider.Factory {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
@ -994,8 +972,7 @@ class CollectionViewModel(
|
|||
spaceManager = spaceManager,
|
||||
getSpaceView = getSpaceView,
|
||||
dateTypeNameProvider = dateTypeNameProvider,
|
||||
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate,
|
||||
getLastSearchQuery = getLastSearchQuery
|
||||
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
@ -1007,7 +984,7 @@ class CollectionViewModel(
|
|||
data class LaunchObjectSet(val target: Id, val space: Id) : Command()
|
||||
|
||||
data object ToDesktop : Command()
|
||||
data class ToSearch(val initialQuery: String, val space: Id) : Command()
|
||||
data class ToSearch(val space: Id) : Command()
|
||||
data object SelectSpace : Command()
|
||||
data object Exit : Command()
|
||||
}
|
||||
|
|
|
@ -124,8 +124,7 @@ class CollectionCreateAndAddObjectTest: ObjectSetViewModelTestSetup() {
|
|||
permissions = permissions,
|
||||
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate,
|
||||
spaceSyncAndP2PStatusProvider = spaceSyncAndP2PStatusProvider,
|
||||
clearLastOpenedObject = clearLastOpenedObject,
|
||||
getLastSearchQuery = getLastSearchQuery
|
||||
clearLastOpenedObject = clearLastOpenedObject
|
||||
)
|
||||
stubNetworkMode()
|
||||
stubObservePermissions()
|
||||
|
|
|
@ -87,7 +87,6 @@ import com.anytypeio.anytype.domain.page.bookmark.CreateBookmarkBlock
|
|||
import com.anytypeio.anytype.domain.page.bookmark.SetupBookmark
|
||||
import com.anytypeio.anytype.domain.relations.AddRelationToObject
|
||||
import com.anytypeio.anytype.domain.relations.SetRelationKey
|
||||
import com.anytypeio.anytype.domain.search.GetLastSearchQuery
|
||||
import com.anytypeio.anytype.domain.search.SearchObjects
|
||||
import com.anytypeio.anytype.domain.sets.FindObjectSetForType
|
||||
import com.anytypeio.anytype.domain.table.CreateTable
|
||||
|
@ -365,9 +364,6 @@ open class EditorViewModelTest {
|
|||
@Mock
|
||||
lateinit var spaceSyncAndP2PStatusProvider: SpaceSyncAndP2PStatusProvider
|
||||
|
||||
@Mock
|
||||
lateinit var getLastSearchQuery: GetLastSearchQuery
|
||||
|
||||
lateinit var vm: EditorViewModel
|
||||
|
||||
private lateinit var builder: UrlBuilder
|
||||
|
@ -3964,8 +3960,7 @@ open class EditorViewModelTest {
|
|||
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate,
|
||||
spaceSyncAndP2PStatusProvider = spaceSyncAndP2PStatusProvider,
|
||||
clearLastOpenedObject = clearLastOpenedObject,
|
||||
getNetworkMode = getNetworkMode,
|
||||
getLastSearchQuery = getLastSearchQuery
|
||||
getNetworkMode = getNetworkMode
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,6 @@ import com.anytypeio.anytype.domain.page.bookmark.CreateBookmarkBlock
|
|||
import com.anytypeio.anytype.domain.page.bookmark.SetupBookmark
|
||||
import com.anytypeio.anytype.domain.relations.AddRelationToObject
|
||||
import com.anytypeio.anytype.domain.relations.SetRelationKey
|
||||
import com.anytypeio.anytype.domain.search.GetLastSearchQuery
|
||||
import com.anytypeio.anytype.domain.search.SearchObjects
|
||||
import com.anytypeio.anytype.domain.sets.FindObjectSetForType
|
||||
import com.anytypeio.anytype.domain.table.CreateTable
|
||||
|
@ -293,9 +292,6 @@ open class EditorPresentationTestSetup {
|
|||
@Mock
|
||||
lateinit var convertObjectToCollection: ConvertObjectToCollection
|
||||
|
||||
@Mock
|
||||
lateinit var getLastSearchQuery: GetLastSearchQuery
|
||||
|
||||
lateinit var tableDelegate: EditorTableDelegate
|
||||
|
||||
lateinit var dispatcher: Dispatcher<Payload>
|
||||
|
@ -503,8 +499,7 @@ open class EditorPresentationTestSetup {
|
|||
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate,
|
||||
clearLastOpenedObject = clearLastOpenedObject,
|
||||
spaceSyncAndP2PStatusProvider = spaceSyncAndP2PStatusProvider,
|
||||
getNetworkMode = getNetworkMode,
|
||||
getLastSearchQuery = getLastSearchQuery
|
||||
getNetworkMode = getNetworkMode
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,6 @@ 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.CreateObject
|
||||
import com.anytypeio.anytype.domain.search.GetLastSearchQuery
|
||||
import com.anytypeio.anytype.domain.search.SearchObjects
|
||||
import com.anytypeio.anytype.domain.spaces.ClearLastOpenedSpace
|
||||
import com.anytypeio.anytype.domain.spaces.GetSpaceView
|
||||
|
@ -245,9 +244,6 @@ class HomeScreenViewModelTest {
|
|||
@Mock
|
||||
lateinit var addObjectToCollection: AddObjectToCollection
|
||||
|
||||
@Mock
|
||||
lateinit var getLastSearchQuery: GetLastSearchQuery
|
||||
|
||||
@Mock
|
||||
lateinit var clearLastOpenedSpace: ClearLastOpenedSpace
|
||||
|
||||
|
@ -2948,7 +2944,6 @@ class HomeScreenViewModelTest {
|
|||
createDataViewObject = createDataViewObject,
|
||||
dateProvider = dateProvider,
|
||||
addObjectToCollection = addObjectToCollection,
|
||||
getLastSearchQuery = getLastSearchQuery,
|
||||
clearLastOpenedSpace = clearLastOpenedSpace
|
||||
)
|
||||
|
||||
|
|
|
@ -57,7 +57,6 @@ import com.anytypeio.anytype.domain.page.CloseBlock
|
|||
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.GetLastSearchQuery
|
||||
import com.anytypeio.anytype.domain.search.SubscriptionEventChannel
|
||||
import com.anytypeio.anytype.domain.sets.OpenObjectSet
|
||||
import com.anytypeio.anytype.domain.sets.SetQueryToObjectSet
|
||||
|
@ -213,9 +212,6 @@ open class ObjectSetViewModelTestSetup {
|
|||
@Mock
|
||||
lateinit var spaceSyncAndP2PStatusProvider: SpaceSyncAndP2PStatusProvider
|
||||
|
||||
@Mock
|
||||
lateinit var getLastSearchQuery: GetLastSearchQuery
|
||||
|
||||
var permissions: UserPermissionProvider = UserPermissionProviderStub()
|
||||
|
||||
lateinit var spaceConfig: Config
|
||||
|
@ -307,8 +303,7 @@ open class ObjectSetViewModelTestSetup {
|
|||
permissions = permissions,
|
||||
analyticSpaceHelperDelegate = analyticSpaceHelperDelegate,
|
||||
spaceSyncAndP2PStatusProvider = spaceSyncAndP2PStatusProvider,
|
||||
clearLastOpenedObject = clearLastOpenedObject,
|
||||
getLastSearchQuery = getLastSearchQuery
|
||||
clearLastOpenedObject = clearLastOpenedObject
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue