diff --git a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsCache.kt b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsCache.kt index fa9155cdf4..58af2adde5 100644 --- a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsCache.kt +++ b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsCache.kt @@ -44,6 +44,6 @@ interface UserSettingsCache { suspend fun saveWidgetSession(session: WidgetSession) suspend fun clear() - suspend fun getAllContentSort(space: SpaceId): Id - suspend fun setAllContentSort(space: SpaceId, sort: Id) + suspend fun getAllContentSort(space: SpaceId): Pair + suspend fun setAllContentSort(space: SpaceId, sort: Id, isAsc: Boolean) } \ No newline at end of file diff --git a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsDataRepository.kt b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsDataRepository.kt index d649081707..6ec8087473 100644 --- a/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsDataRepository.kt +++ b/data/src/main/java/com/anytypeio/anytype/data/auth/repo/UserSettingsDataRepository.kt @@ -110,11 +110,11 @@ class UserSettingsDataRepository(private val cache: UserSettingsCache) : UserSet ) } - override suspend fun getAllContentSort(space: SpaceId): Id { + override suspend fun getAllContentSort(space: SpaceId): Pair { return cache.getAllContentSort(space) } - override suspend fun setAllContentSort(space: SpaceId, sort: Id) { - cache.setAllContentSort(space, sort) + override suspend fun setAllContentSort(space: SpaceId, sort: Id, isAsc: Boolean) { + cache.setAllContentSort(space, sort, isAsc) } } \ No newline at end of file diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/all_content/RestoreAllContentState.kt b/domain/src/main/java/com/anytypeio/anytype/domain/all_content/RestoreAllContentState.kt index 1dcd392dae..8e05e50c55 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/all_content/RestoreAllContentState.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/all_content/RestoreAllContentState.kt @@ -14,8 +14,8 @@ class RestoreAllContentState @Inject constructor( ) { override suspend fun doWork(params: Params): Response { - val sort = settings.getAllContentSort(params.spaceId) - return Response(activeSort = sort) + val res = settings.getAllContentSort(params.spaceId) + return Response(activeSort = res.first, isAsc = res.second) } data class Params( @@ -23,6 +23,7 @@ class RestoreAllContentState @Inject constructor( ) data class Response( - val activeSort: String? + val activeSort: String?, + val isAsc: Boolean ) } \ No newline at end of file diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/all_content/UpdateAllContentState.kt b/domain/src/main/java/com/anytypeio/anytype/domain/all_content/UpdateAllContentState.kt index 8ee62d8a2d..773ca0da4d 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/all_content/UpdateAllContentState.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/all_content/UpdateAllContentState.kt @@ -15,12 +15,14 @@ class UpdateAllContentState @Inject constructor( override suspend fun doWork(params: Params) { settings.setAllContentSort( space = params.spaceId, - sort = params.sort + sort = params.sort, + isAsc = params.isAsc ) } data class Params( val spaceId: SpaceId, - val sort: Id + val sort: Id, + val isAsc: Boolean ) } \ No newline at end of file diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/config/UserSettingsRepository.kt b/domain/src/main/java/com/anytypeio/anytype/domain/config/UserSettingsRepository.kt index cea8576d30..db2bae3590 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/config/UserSettingsRepository.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/config/UserSettingsRepository.kt @@ -46,8 +46,8 @@ interface UserSettingsRepository { suspend fun getWidgetSession() : WidgetSession suspend fun saveWidgetSession(session: WidgetSession) - suspend fun getAllContentSort(space: SpaceId): Id - suspend fun setAllContentSort(space: SpaceId, sort: Id) + suspend fun getAllContentSort(space: SpaceId): Pair + suspend fun setAllContentSort(space: SpaceId, sort: Id, isAsc: Boolean) suspend fun clear() } \ No newline at end of file diff --git a/feature-all-content/src/main/java/com/anytypeio/anytype/feature_allcontent/presentation/AllContentViewModel.kt b/feature-all-content/src/main/java/com/anytypeio/anytype/feature_allcontent/presentation/AllContentViewModel.kt index cb70263ac1..8579bd4a1f 100644 --- a/feature-all-content/src/main/java/com/anytypeio/anytype/feature_allcontent/presentation/AllContentViewModel.kt +++ b/feature-all-content/src/main/java/com/anytypeio/anytype/feature_allcontent/presentation/AllContentViewModel.kt @@ -73,9 +73,9 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.emitAll import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onCompletion +import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.take import kotlinx.coroutines.launch @@ -221,14 +221,7 @@ class AllContentViewModel( } } - //todo discuss with someone - private fun loadData(): Flow> = flow { - - uiContentState.value = if (itemsLimit == DEFAULT_SEARCH_LIMIT) { - UiContentState.InitLoading - } else { - UiContentState.Paging - } + private fun loadData(): Flow> { val activeTab = uiTabsState.value.selectedTab val activeSort = sortState.value @@ -243,31 +236,50 @@ class AllContentViewModel( activeMode = uiTitleState.value ) - Timber.d("Restart subscription: with params: $searchParams") - - val dataFlow = storelessSubscriptionContainer.subscribe(searchParams) - emitAll( - dataFlow.map { objWrappers -> - canPaginate.value = objWrappers.size == itemsLimit - val items = mapToUiContentItems( - objectWrappers = objWrappers, - activeSort = activeSort, - activeTab = activeTab - ) - uiContentState.value = if (items.isEmpty()) { - UiContentState.Empty + return storelessSubscriptionContainer.subscribe(searchParams) + .onStart { + uiContentState.value = if (itemsLimit == DEFAULT_SEARCH_LIMIT) { + UiContentState.InitLoading } else { - UiContentState.Idle(scrollToTop = shouldScrollToTopItems).also { - shouldScrollToTopItems = false - } + UiContentState.Paging } - items - }.catch { e -> - uiContentState.value = UiContentState.Error( - message = e.message ?: "An error occurred while loading data." - ) - emit(emptyList()) + Timber.d("Restart subscription: with params: $searchParams") } + .map { objWrappers -> + handleData(objWrappers, activeSort, activeTab) + }.catch { e -> + handleError(e) + } + } + + private suspend fun handleData( + objWrappers: List, + activeSort: AllContentSort, + activeTab: AllContentTab + ): List { + + canPaginate.value = objWrappers.size == itemsLimit + + val items = mapToUiContentItems( + objectWrappers = objWrappers, + activeSort = activeSort, + activeTab = activeTab + ) + + uiContentState.value = if (items.isEmpty()) { + UiContentState.Empty + } else { + UiContentState.Idle(scrollToTop = shouldScrollToTopItems).also { + shouldScrollToTopItems = false + } + } + + return items + } + + private fun handleError(e: Throwable) { + uiContentState.value = UiContentState.Error( + message = e.message ?: "An error occurred while loading data." ) } @@ -301,11 +313,11 @@ class AllContentViewModel( ) val result = when (activeSort) { is AllContentSort.ByDateCreated -> { - groupItemsByDate(items = items, isSortByDateCreated = true) + groupItemsByDate(items = items, isSortByDateCreated = true, activeSort = activeSort) } is AllContentSort.ByDateUpdated -> { - groupItemsByDate(items = items, isSortByDateCreated = false) + groupItemsByDate(items = items, isSortByDateCreated = false, activeSort = activeSort) } is AllContentSort.ByName -> { @@ -323,12 +335,28 @@ class AllContentViewModel( private fun groupItemsByDate( items: List, - isSortByDateCreated: Boolean + isSortByDateCreated: Boolean, + activeSort: AllContentSort ): List { + val groupedItems = mutableListOf() var currentGroupKey: String? = null - for (item in items) { + val sortedItems = if (isSortByDateCreated) { + if (activeSort.sortType == DVSortType.ASC) { + items.sortedBy { it.createdDate } + } else { + items.sortedByDescending { it.createdDate } + } + } else { + if (activeSort.sortType == DVSortType.ASC) { + items.sortedBy { it.lastModifiedDate } + } else { + items.sortedByDescending { it.lastModifiedDate } + } + } + + for (item in sortedItems) { val timestamp = if (isSortByDateCreated) { item.createdDate } else { @@ -562,7 +590,8 @@ class AllContentViewModel( viewModelScope.launch { val params = UpdateAllContentState.Params( spaceId = vmParams.spaceId, - sort = sort.relationKey.key + sort = sort.relationKey.key, + isAsc = sort.sortType == DVSortType.ASC ) updateAllContentState.async(params).fold( onSuccess = { @@ -732,6 +761,12 @@ class AllContentViewModel( viewModelScope.launch { storelessSubscriptionContainer.unsubscribe(listOf(subscriptionId())) } + viewModelScope.launch { + userInput.value = DEFAULT_QUERY + searchResultIds.value = emptyList() + uiItemsState.value = emptyList() + uiContentState.value = UiContentState.Empty + } } fun proceedWithMoveToBin(item: UiContentItem.Item) { diff --git a/persistence/src/main/java/com/anytypeio/anytype/persistence/repo/DefaultUserSettingsCache.kt b/persistence/src/main/java/com/anytypeio/anytype/persistence/repo/DefaultUserSettingsCache.kt index e1db495060..aa6bb063b6 100644 --- a/persistence/src/main/java/com/anytypeio/anytype/persistence/repo/DefaultUserSettingsCache.kt +++ b/persistence/src/main/java/com/anytypeio/anytype/persistence/repo/DefaultUserSettingsCache.kt @@ -458,20 +458,19 @@ class DefaultUserSettingsCache( } } - override suspend fun getAllContentSort(space: SpaceId): Id { + override suspend fun getAllContentSort(space: SpaceId): Pair { return context.spacePrefsStore .data .map { preferences -> - preferences - .preferences[space.id] - ?.allContent - ?.sortKey - .orEmpty() + val pref = preferences.preferences[space.id]?.allContent + val sortKey = pref?.sortKey.orEmpty() + val isAsc = pref?.isAscending ?: true + sortKey to isAsc } .first() } - override suspend fun setAllContentSort(space: SpaceId, sort: Id) { + override suspend fun setAllContentSort(space: SpaceId, sort: Id, isAsc: Boolean) { context.spacePrefsStore.updateData { existingPreferences -> val givenSpacePreference = existingPreferences .preferences @@ -481,7 +480,8 @@ class DefaultUserSettingsCache( ) val updated = givenSpacePreference.copy( allContent = AllContentSettings( - sortKey = sort + sortKey = sort, + isAscending = isAsc ) ) val result = buildMap { diff --git a/persistence/src/main/proto/preferences.proto b/persistence/src/main/proto/preferences.proto index 8e2dd7fc5c..5c896b7576 100644 --- a/persistence/src/main/proto/preferences.proto +++ b/persistence/src/main/proto/preferences.proto @@ -33,4 +33,5 @@ message GlobalSearchHistoryProto { message AllContentSettings { optional string sortKey = 1; + optional bool isAscending = 2; } \ No newline at end of file diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/search/ObjectSearchConstants.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/search/ObjectSearchConstants.kt index f1d76101ed..602207bc9e 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/search/ObjectSearchConstants.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/search/ObjectSearchConstants.kt @@ -655,7 +655,8 @@ object ObjectSearchConstants { Relations.CREATED_DATE, Relations.LINKS, Relations.BACKLINKS, - Relations.LAST_USED_DATE + Relations.LAST_USED_DATE, + Relations.DESCRIPTION ) val defaultOptionKeys = listOf(