diff --git a/app/src/androidTest/java/com/anytypeio/anytype/features/sets/dv/TestObjectSetSetup.kt b/app/src/androidTest/java/com/anytypeio/anytype/features/sets/dv/TestObjectSetSetup.kt index 193e8fe1b6..f40a6cd52f 100644 --- a/app/src/androidTest/java/com/anytypeio/anytype/features/sets/dv/TestObjectSetSetup.kt +++ b/app/src/androidTest/java/com/anytypeio/anytype/features/sets/dv/TestObjectSetSetup.kt @@ -13,6 +13,7 @@ import com.anytypeio.anytype.core_models.Relation import com.anytypeio.anytype.core_models.SearchResult import com.anytypeio.anytype.core_models.SubscriptionEvent import com.anytypeio.anytype.core_models.primitives.SpaceId +import com.anytypeio.anytype.device.providers.AppDefaultDateFormatProviderImpl import com.anytypeio.anytype.device.providers.DateProviderImpl import com.anytypeio.anytype.domain.auth.interactor.ClearLastOpenedObject import com.anytypeio.anytype.domain.auth.repo.AuthRepository @@ -81,7 +82,6 @@ import java.util.Locale import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.test.StandardTestDispatcher -import kotlinx.coroutines.test.TestScope import org.mockito.Mock import org.mockito.Mockito import org.mockito.MockitoAnnotations @@ -242,8 +242,7 @@ abstract class TestObjectSetSetup { private val dateProvider = DateProviderImpl( defaultZoneId = ZoneId.systemDefault(), localeProvider = localeProvider, - vaultSettings = observeVaultSettings, - scope = TestScope() + appDefaultDateFormatProvider = AppDefaultDateFormatProviderImpl(localeProvider) ) open fun setup() { diff --git a/app/src/main/java/com/anytypeio/anytype/di/feature/home/HomescreenDI.kt b/app/src/main/java/com/anytypeio/anytype/di/feature/home/HomescreenDI.kt index 8b24d24189..7320b467dc 100644 --- a/app/src/main/java/com/anytypeio/anytype/di/feature/home/HomescreenDI.kt +++ b/app/src/main/java/com/anytypeio/anytype/di/feature/home/HomescreenDI.kt @@ -33,6 +33,7 @@ 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.primitives.FieldParser import com.anytypeio.anytype.domain.search.SubscriptionEventChannel import com.anytypeio.anytype.domain.templates.GetTemplates import com.anytypeio.anytype.domain.workspace.NotificationsChannel @@ -276,4 +277,5 @@ interface HomeScreenDependencies : ComponentDependencies { fun spaceViewSubscriptionContainer(): SpaceViewSubscriptionContainer fun featureToggles(): FeatureToggles fun payloadDelegator(): PayloadDelegator + fun fieldParser(): FieldParser } \ No newline at end of file diff --git a/app/src/main/java/com/anytypeio/anytype/di/main/UtilModule.kt b/app/src/main/java/com/anytypeio/anytype/di/main/UtilModule.kt index a6b091a683..000f70d294 100644 --- a/app/src/main/java/com/anytypeio/anytype/di/main/UtilModule.kt +++ b/app/src/main/java/com/anytypeio/anytype/di/main/UtilModule.kt @@ -13,8 +13,8 @@ import com.anytypeio.anytype.core_utils.tools.DefaultUrlValidator import com.anytypeio.anytype.core_utils.tools.FeatureToggles import com.anytypeio.anytype.core_utils.tools.ThreadInfo import com.anytypeio.anytype.core_utils.tools.UrlValidator +import com.anytypeio.anytype.device.providers.AppDefaultDateFormatProvider import com.anytypeio.anytype.device.providers.DateProviderImpl -import com.anytypeio.anytype.di.main.ConfigModule.DEFAULT_APP_COROUTINE_SCOPE import com.anytypeio.anytype.domain.config.Gateway import com.anytypeio.anytype.domain.debugging.DebugConfig import com.anytypeio.anytype.domain.debugging.Logger @@ -24,7 +24,6 @@ import com.anytypeio.anytype.domain.misc.LocaleProvider import com.anytypeio.anytype.domain.misc.UrlBuilder import com.anytypeio.anytype.domain.primitives.FieldParser import com.anytypeio.anytype.domain.primitives.FieldParserImpl -import com.anytypeio.anytype.domain.vault.ObserveVaultSettings import com.anytypeio.anytype.middleware.interactor.MiddlewareProtobufLogger import com.anytypeio.anytype.middleware.interactor.ProtobufConverterProvider import com.anytypeio.anytype.other.BasicLogger @@ -34,9 +33,7 @@ import dagger.Binds import dagger.Module import dagger.Provides import java.time.ZoneId -import javax.inject.Named import javax.inject.Singleton -import kotlinx.coroutines.CoroutineScope @Module(includes = [UtilModule.Bindings::class]) object UtilModule { @@ -64,13 +61,11 @@ object UtilModule { @Singleton fun provideDateProvider( localeProvider: LocaleProvider, - observeVaultSettings: ObserveVaultSettings, - @Named(DEFAULT_APP_COROUTINE_SCOPE) scope: CoroutineScope + appDefaultDateFormatProvider: AppDefaultDateFormatProvider ): DateProvider = DateProviderImpl( defaultZoneId = ZoneId.systemDefault(), localeProvider = localeProvider, - vaultSettings = observeVaultSettings, - scope = scope + appDefaultDateFormatProvider = appDefaultDateFormatProvider ) @JvmStatic diff --git a/core-models/src/main/java/com/anytypeio/anytype/core_models/Constants.kt b/core-models/src/main/java/com/anytypeio/anytype/core_models/Constants.kt index 9fc2070bf5..78c2d00037 100644 --- a/core-models/src/main/java/com/anytypeio/anytype/core_models/Constants.kt +++ b/core-models/src/main/java/com/anytypeio/anytype/core_models/Constants.kt @@ -23,7 +23,7 @@ const val DEFAULT_SHOW_INTRODUCE_VAULT = true /** * The default value for showing the time */ -const val DEFAULT_TIME_STYLE = DateFormat.DEFAULT +const val DEFAULT_DATE_FORMAT_STYLE = DateFormat.DEFAULT /** * The date range for the date picker. diff --git a/device/src/main/java/com/anytypeio/anytype/device/providers/AppDefaultDateFormatProvider.kt b/device/src/main/java/com/anytypeio/anytype/device/providers/AppDefaultDateFormatProvider.kt index aa9cb34d54..5b85ad2fbb 100644 --- a/device/src/main/java/com/anytypeio/anytype/device/providers/AppDefaultDateFormatProvider.kt +++ b/device/src/main/java/com/anytypeio/anytype/device/providers/AppDefaultDateFormatProvider.kt @@ -1,6 +1,6 @@ package com.anytypeio.anytype.device.providers -import com.anytypeio.anytype.core_models.DEFAULT_TIME_STYLE +import com.anytypeio.anytype.core_models.DEFAULT_DATE_FORMAT_STYLE import com.anytypeio.anytype.core_models.FALLBACK_DATE_PATTERN import com.anytypeio.anytype.domain.misc.LocaleProvider import java.text.DateFormat @@ -34,7 +34,7 @@ class AppDefaultDateFormatProviderImpl @Inject constructor( override fun provide(): String { return try { val locale = localeProvider.locale() - val dateFormat = DateFormat.getDateInstance(DEFAULT_TIME_STYLE, locale) + val dateFormat = DateFormat.getDateInstance(DEFAULT_DATE_FORMAT_STYLE, locale) if (dateFormat is SimpleDateFormat) { dateFormat.toPattern() } else { diff --git a/device/src/main/java/com/anytypeio/anytype/device/providers/DateProviderImpl.kt b/device/src/main/java/com/anytypeio/anytype/device/providers/DateProviderImpl.kt index a18347572d..09d1b1a69b 100644 --- a/device/src/main/java/com/anytypeio/anytype/device/providers/DateProviderImpl.kt +++ b/device/src/main/java/com/anytypeio/anytype/device/providers/DateProviderImpl.kt @@ -1,14 +1,12 @@ package com.anytypeio.anytype.device.providers import android.text.format.DateUtils -import com.anytypeio.anytype.core_models.FALLBACK_DATE_PATTERN import com.anytypeio.anytype.core_models.RelativeDate import com.anytypeio.anytype.core_models.TimeInMillis import com.anytypeio.anytype.core_models.TimeInSeconds import com.anytypeio.anytype.domain.misc.DateProvider import com.anytypeio.anytype.domain.misc.DateType import com.anytypeio.anytype.domain.misc.LocaleProvider -import com.anytypeio.anytype.domain.vault.ObserveVaultSettings import java.text.DateFormat import java.text.SimpleDateFormat import java.time.Instant @@ -20,27 +18,15 @@ import java.time.temporal.ChronoUnit import java.util.Date import java.util.concurrent.TimeUnit import javax.inject.Inject -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.launch import timber.log.Timber class DateProviderImpl @Inject constructor( private val defaultZoneId: ZoneId, private val localeProvider: LocaleProvider, - private val vaultSettings: ObserveVaultSettings, - scope: CoroutineScope + private val appDefaultDateFormatProvider: AppDefaultDateFormatProvider ) : DateProvider { - private val defaultDateFormat = MutableStateFlow(FALLBACK_DATE_PATTERN) - - init { - scope.launch { - vaultSettings.flow().collect { settings -> - defaultDateFormat.value = settings.dateFormat - } - } - } + private val defaultDateFormat get() = appDefaultDateFormatProvider.provide() override fun calculateDateType(date: TimeInSeconds): DateType { val dateInstant = Instant.ofEpochSecond(date) @@ -172,10 +158,9 @@ class DateProviderImpl @Inject constructor( timestamp: TimeInMillis, timeStyle: Int ): Pair { - Timber.d("Formatting timestamp [$timestamp] to date and time") return try { val locale = localeProvider.locale() - val datePattern = defaultDateFormat.value + val datePattern = defaultDateFormat val timePattern = (DateFormat.getTimeInstance(timeStyle, locale) as SimpleDateFormat).toPattern() val dateFormatter = SimpleDateFormat(datePattern, locale) diff --git a/device/src/test/java/com/anytypeio/anytype/DateProviderImplTest.kt b/device/src/test/java/com/anytypeio/anytype/DateProviderImplTest.kt index 5c90a59e0a..85e1303d78 100644 --- a/device/src/test/java/com/anytypeio/anytype/DateProviderImplTest.kt +++ b/device/src/test/java/com/anytypeio/anytype/DateProviderImplTest.kt @@ -1,5 +1,7 @@ package com.anytypeio.anytype +import com.anytypeio.anytype.device.providers.AppDefaultDateFormatProvider +import com.anytypeio.anytype.device.providers.AppDefaultDateFormatProviderImpl import com.anytypeio.anytype.device.providers.DateProviderImpl import com.anytypeio.anytype.domain.misc.DateProvider import com.anytypeio.anytype.domain.misc.LocaleProvider @@ -27,9 +29,12 @@ class DateProviderImplTest { lateinit var dateProviderImpl: DateProvider + lateinit var appDefaultDateFormatProvider: AppDefaultDateFormatProvider + @Before fun setUp() { MockitoAnnotations.openMocks(this) + appDefaultDateFormatProvider = AppDefaultDateFormatProviderImpl(localeProvider) Mockito.`when`(localeProvider.locale()).thenReturn(Locale.getDefault()) Mockito.`when`(localeProvider.language()).thenReturn("en") } @@ -72,8 +77,7 @@ class DateProviderImplTest { dateProviderImpl = DateProviderImpl( defaultZoneId = zoneId, localeProvider = localeProvider, - vaultSettings = observeVaultSettings, - scope = backgroundScope + appDefaultDateFormatProvider = appDefaultDateFormatProvider, ) val startOfDayInLocalZone = dateProviderImpl.adjustFromStartOfDayInUserTimeZoneToUTC( @@ -122,8 +126,7 @@ class DateProviderImplTest { dateProviderImpl = DateProviderImpl( defaultZoneId = zoneId, localeProvider = localeProvider, - vaultSettings = observeVaultSettings, - scope = backgroundScope + appDefaultDateFormatProvider = appDefaultDateFormatProvider, ) val startOfDayInLocalZone = dateProviderImpl.adjustFromStartOfDayInUserTimeZoneToUTC(utcTimestamp * 1000) @@ -169,8 +172,7 @@ class DateProviderImplTest { dateProviderImpl = DateProviderImpl( defaultZoneId = zoneId, localeProvider = localeProvider, - vaultSettings = observeVaultSettings, - scope = backgroundScope + appDefaultDateFormatProvider = appDefaultDateFormatProvider, ) val startOfDayInLocalZone = dateProviderImpl.adjustFromStartOfDayInUserTimeZoneToUTC(utcTimestamp * 1000) @@ -215,8 +217,7 @@ class DateProviderImplTest { dateProviderImpl = DateProviderImpl( defaultZoneId = zoneId, localeProvider = localeProvider, - vaultSettings = observeVaultSettings, - scope = backgroundScope + appDefaultDateFormatProvider = appDefaultDateFormatProvider, ) val startOfDayInLocalZone = dateProviderImpl.adjustFromStartOfDayInUserTimeZoneToUTC(utcTimestamp * 1000) diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/misc/DateProvider.kt b/domain/src/main/java/com/anytypeio/anytype/domain/misc/DateProvider.kt index a1e499d1e5..119f24df35 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/misc/DateProvider.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/misc/DateProvider.kt @@ -1,6 +1,6 @@ package com.anytypeio.anytype.domain.misc -import com.anytypeio.anytype.core_models.DEFAULT_TIME_STYLE +import com.anytypeio.anytype.core_models.DEFAULT_DATE_FORMAT_STYLE import com.anytypeio.anytype.core_models.RelativeDate import com.anytypeio.anytype.core_models.TimeInMillis import com.anytypeio.anytype.core_models.TimeInSeconds @@ -24,7 +24,7 @@ interface DateProvider { fun formatToDateString(timestamp: Long, pattern: String): String fun formatTimestampToDateAndTime( timestamp: TimeInMillis, - timeStyle: Int = DEFAULT_TIME_STYLE + timeStyle: Int = DEFAULT_DATE_FORMAT_STYLE ): Pair fun calculateRelativeDates(dateInSeconds: TimeInSeconds?): RelativeDate? fun isSameMinute(timestamp1: Long, timestamp2: Long): Boolean diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/home/HomeScreenViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/home/HomeScreenViewModel.kt index 0a29ed2021..1c319b3c02 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/home/HomeScreenViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/home/HomeScreenViewModel.kt @@ -22,6 +22,7 @@ import com.anytypeio.anytype.core_models.ObjectWrapper import com.anytypeio.anytype.core_models.Payload import com.anytypeio.anytype.core_models.Position import com.anytypeio.anytype.core_models.Relations +import com.anytypeio.anytype.core_models.SupportedLayouts import com.anytypeio.anytype.core_models.WidgetLayout import com.anytypeio.anytype.core_models.WidgetSession import com.anytypeio.anytype.core_models.ext.process @@ -62,6 +63,7 @@ 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.primitives.FieldParser import com.anytypeio.anytype.domain.search.SearchObjects import com.anytypeio.anytype.domain.spaces.ClearLastOpenedSpace import com.anytypeio.anytype.domain.spaces.GetSpaceView @@ -87,7 +89,6 @@ import com.anytypeio.anytype.presentation.extension.sendSelectHomeTabEvent import com.anytypeio.anytype.presentation.home.Command.ChangeWidgetType.Companion.UNDEFINED_LAYOUT_CODE import com.anytypeio.anytype.presentation.navigation.DeepLinkToObjectDelegate import com.anytypeio.anytype.presentation.navigation.NavigationViewModel -import com.anytypeio.anytype.core_models.SupportedLayouts import com.anytypeio.anytype.presentation.objects.getCreateObjectParams import com.anytypeio.anytype.presentation.search.Subscriptions import com.anytypeio.anytype.presentation.sets.prefillNewObjectDetails @@ -205,7 +206,8 @@ class HomeScreenViewModel( private val clearLastOpenedSpace: ClearLastOpenedSpace, private val clearLastOpenedObject: ClearLastOpenedObject, private val spaceBinWidgetContainer: SpaceBinWidgetContainer, - private val featureToggles: FeatureToggles + private val featureToggles: FeatureToggles, + private val fieldParser: FieldParser ) : NavigationViewModel(), Reducer, WidgetActiveViewStateHolder by widgetActiveViewStateHolder, @@ -450,7 +452,8 @@ class HomeScreenViewModel( widgets.filter { widget -> widget.hasValidLayout() }.map { widget -> when (widget) { is Widget.Link -> LinkWidgetContainer( - widget = widget + widget = widget, + fieldParser = fieldParser ) is Widget.Tree -> TreeWidgetContainer( widget = widget, @@ -467,7 +470,8 @@ class HomeScreenViewModel( && view is WidgetView.Tree && view.source == widget.source } as? WidgetView.Tree - } + }, + fieldParser = fieldParser ) is Widget.List -> if (BundledWidgetSourceIds.ids.contains(widget.source.id)) { ListWidgetContainer( @@ -485,7 +489,8 @@ class HomeScreenViewModel( && view is WidgetView.ListOfObjects && view.source == widget.source } as? WidgetView.ListOfObjects - } + }, + fieldParser = fieldParser ) } else { DataViewListWidgetContainer( @@ -504,7 +509,8 @@ class HomeScreenViewModel( && view.source == widget.source } as? WidgetView.SetOfObjects }, - storeOfRelations = storeOfRelations + storeOfRelations = storeOfRelations, + fieldParser = fieldParser ) } is Widget.View -> { @@ -525,7 +531,8 @@ class HomeScreenViewModel( && view.source == widget.source } as? WidgetView.SetOfObjects }, - storeOfRelations = storeOfRelations + storeOfRelations = storeOfRelations, + fieldParser = fieldParser ) } } @@ -2188,7 +2195,8 @@ class HomeScreenViewModel( private val clearLastOpenedSpace: ClearLastOpenedSpace, private val clearLastOpenedObject: ClearLastOpenedObject, private val spaceBinWidgetContainer: SpaceBinWidgetContainer, - private val featureToggles: FeatureToggles + private val featureToggles: FeatureToggles, + private val fieldParser: FieldParser ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T = HomeScreenViewModel( @@ -2239,7 +2247,8 @@ class HomeScreenViewModel( clearLastOpenedSpace = clearLastOpenedSpace, clearLastOpenedObject = clearLastOpenedObject, spaceBinWidgetContainer = spaceBinWidgetContainer, - featureToggles = featureToggles + featureToggles = featureToggles, + fieldParser = fieldParser ) as T } diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/DataViewListWidgetContainer.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/DataViewListWidgetContainer.kt index d3a193f0dd..74f5284d28 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/DataViewListWidgetContainer.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/DataViewListWidgetContainer.kt @@ -16,6 +16,7 @@ import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer import com.anytypeio.anytype.domain.misc.UrlBuilder import com.anytypeio.anytype.domain.`object`.GetObject import com.anytypeio.anytype.domain.objects.StoreOfRelations +import com.anytypeio.anytype.domain.primitives.FieldParser import com.anytypeio.anytype.presentation.BuildConfig import com.anytypeio.anytype.presentation.editor.cover.CoverImageHashProvider import com.anytypeio.anytype.presentation.mapper.objectIcon @@ -43,6 +44,7 @@ class DataViewListWidgetContainer( private val isWidgetCollapsed: Flow, private val coverImageHashProvider: CoverImageHashProvider, private val storeOfRelations: StoreOfRelations, + private val fieldParser: FieldParser, isSessionActive: Flow, onRequestCache: () -> WidgetView.SetOfObjects? = { null }, ) : WidgetContainer { @@ -70,7 +72,7 @@ class DataViewListWidgetContainer( name = when(val source = widget.source) { is Widget.Source.Bundled -> WidgetView.Name.Bundled(source = source) is Widget.Source.Default -> WidgetView.Name.Default( - prettyPrintName = source.obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(source.obj) ) } ) @@ -84,7 +86,7 @@ class DataViewListWidgetContainer( isExpanded = !isCollapsed, isLoading = true, name = WidgetView.Name.Default( - prettyPrintName = widget.source.obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(widget.source.obj) ) ) } @@ -125,7 +127,7 @@ class DataViewListWidgetContainer( name = when(val source = widget.source) { is Widget.Source.Bundled -> WidgetView.Name.Bundled(source = source) is Widget.Source.Default -> WidgetView.Name.Default( - prettyPrintName = source.obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(source.obj) ) } ) @@ -140,7 +142,7 @@ class DataViewListWidgetContainer( elements = emptyList(), isExpanded = false, name = WidgetView.Name.Default( - prettyPrintName = source.obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(source.obj) ) ) ) @@ -261,7 +263,7 @@ class DataViewListWidgetContainer( null }, name = WidgetView.Name.Default( - prettyPrintName = obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(obj) ) ) }, @@ -271,7 +273,7 @@ class DataViewListWidgetContainer( name = when(val source = widget.source) { is Widget.Source.Bundled -> WidgetView.Name.Bundled(source = source) is Widget.Source.Default -> WidgetView.Name.Default( - prettyPrintName = source.obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(source.obj) ) } ) @@ -299,7 +301,7 @@ class DataViewListWidgetContainer( obj = obj, objectIcon = obj.objectIcon(builder = urlBuilder), name = WidgetView.Name.Default( - prettyPrintName = obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(obj) ) ) }, @@ -308,7 +310,7 @@ class DataViewListWidgetContainer( name = when(val source = widget.source) { is Widget.Source.Bundled -> WidgetView.Name.Bundled(source = source) is Widget.Source.Default -> WidgetView.Name.Default( - prettyPrintName = source.obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(source.obj) ) } ) @@ -327,7 +329,7 @@ class DataViewListWidgetContainer( name = when(val source = widget.source) { is Widget.Source.Bundled -> WidgetView.Name.Bundled(source = source) is Widget.Source.Default -> WidgetView.Name.Default( - prettyPrintName = source.obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(source.obj) ) } ) @@ -339,7 +341,7 @@ class DataViewListWidgetContainer( isExpanded = true, view = null, name = WidgetView.Name.Default( - prettyPrintName = widget.source.obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(widget.source.obj) ) ) is Widget.Link, is Widget.Tree -> { diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/LinkWidgetContainer.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/LinkWidgetContainer.kt index 9e1e250ef8..186126c3f2 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/LinkWidgetContainer.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/LinkWidgetContainer.kt @@ -1,10 +1,12 @@ package com.anytypeio.anytype.presentation.widgets +import com.anytypeio.anytype.domain.primitives.FieldParser import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf class LinkWidgetContainer( - widget: Widget + widget: Widget, + fieldParser: FieldParser ) : WidgetContainer { override val view: Flow = flowOf( WidgetView.Link( @@ -13,7 +15,7 @@ class LinkWidgetContainer( name = when(val source = widget.source) { is Widget.Source.Bundled -> WidgetView.Name.Bundled(source = source) is Widget.Source.Default -> WidgetView.Name.Default( - prettyPrintName = source.obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(source.obj) ) } ) diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/ListWidgetContainer.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/ListWidgetContainer.kt index 58668afc4c..4767f4a83a 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/ListWidgetContainer.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/ListWidgetContainer.kt @@ -14,6 +14,7 @@ import com.anytypeio.anytype.domain.library.StoreSearchParams import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer import com.anytypeio.anytype.domain.misc.UrlBuilder import com.anytypeio.anytype.domain.objects.ObjectWatcher +import com.anytypeio.anytype.domain.primitives.FieldParser import com.anytypeio.anytype.domain.spaces.GetSpaceView import com.anytypeio.anytype.presentation.mapper.objectIcon import com.anytypeio.anytype.presentation.search.ObjectSearchConstants @@ -37,6 +38,7 @@ class ListWidgetContainer( private val isWidgetCollapsed: Flow, private val objectWatcher: ObjectWatcher, private val getSpaceView: GetSpaceView, + private val fieldParser: FieldParser, isSessionActive: Flow, onRequestCache: () -> WidgetView.ListOfObjects? = { null } ) : WidgetContainer { @@ -104,7 +106,8 @@ class ListWidgetContainer( .filter { obj -> obj.isArchived != true && obj.isDeleted != true } - .sortedBy { obj -> order[obj.id] } + .sortedBy { obj -> order[obj.id] }, + fieldParser = fieldParser ) } } @@ -126,7 +129,8 @@ class ListWidgetContainer( ) ).map { objects -> buildWidgetViewWithElements( - objects = objects + objects = objects, + fieldParser = fieldParser ) } } @@ -134,7 +138,8 @@ class ListWidgetContainer( else -> { storage.subscribe(buildParams()).map { objects -> buildWidgetViewWithElements( - objects = objects + objects = objects, + fieldParser = fieldParser ) } } @@ -144,6 +149,7 @@ class ListWidgetContainer( private fun buildWidgetViewWithElements( objects: List, + fieldParser: FieldParser ) = WidgetView.ListOfObjects( id = widget.id, source = widget.source, @@ -155,7 +161,7 @@ class ListWidgetContainer( builder = urlBuilder ), name = WidgetView.Name.Default( - prettyPrintName = obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(obj) ) ) }, diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/TreeWidgetContainer.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/TreeWidgetContainer.kt index 41842c2504..52082fd79a 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/TreeWidgetContainer.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/TreeWidgetContainer.kt @@ -9,6 +9,7 @@ import com.anytypeio.anytype.domain.library.StoreSearchByIdsParams import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer import com.anytypeio.anytype.domain.misc.UrlBuilder import com.anytypeio.anytype.domain.objects.ObjectWatcher +import com.anytypeio.anytype.domain.primitives.FieldParser import com.anytypeio.anytype.domain.spaces.GetSpaceView import com.anytypeio.anytype.presentation.mapper.objectIcon import com.anytypeio.anytype.presentation.search.ObjectSearchConstants @@ -33,6 +34,7 @@ class TreeWidgetContainer( private val isWidgetCollapsed: Flow, private val objectWatcher: ObjectWatcher, private val getSpaceView: GetSpaceView, + private val fieldParser: FieldParser, isSessionActive: Flow, onRequestCache: () -> WidgetView.Tree? = { null } ) : WidgetContainer { @@ -56,7 +58,7 @@ class TreeWidgetContainer( name = when(val source = widget.source) { is Widget.Source.Bundled -> WidgetView.Name.Bundled(source = source) is Widget.Source.Default -> WidgetView.Name.Default( - prettyPrintName = source.obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(source.obj) ) } ) @@ -161,7 +163,7 @@ class TreeWidgetContainer( rootLimit = WidgetConfig.NO_LIMIT ), name = WidgetView.Name.Default( - prettyPrintName = source.obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(source.obj) ) ) } @@ -284,7 +286,7 @@ class TreeWidgetContainer( indent = level, path = path + link, name = WidgetView.Name.Default( - prettyPrintName = obj.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(obj) ) ) ) diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/WidgetView.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/WidgetView.kt index 2f91916d63..3dae8cc423 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/WidgetView.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/WidgetView.kt @@ -1,7 +1,6 @@ package com.anytypeio.anytype.presentation.widgets import com.anytypeio.anytype.core_models.Id -import com.anytypeio.anytype.core_models.ObjectType import com.anytypeio.anytype.core_models.ObjectWrapper import com.anytypeio.anytype.core_models.SHARED_SPACE_TYPE import com.anytypeio.anytype.core_models.SpaceType @@ -170,13 +169,4 @@ sealed class DropDownMenuAction { data object AddBelow: DropDownMenuAction() data object EditWidgets : DropDownMenuAction() data object EmptyBin: DropDownMenuAction() -} - -// TODO extend to support date object name or consider creating another extension function -fun ObjectWrapper.Basic.getWidgetObjectName(): String? { - return if (layout == ObjectType.Layout.NOTE) { - snippet?.trim()?.ifEmpty { null } - } else { - name?.trim()?.ifEmpty { null } - } } \ No newline at end of file diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/home/HomeScreenViewModelTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/home/HomeScreenViewModelTest.kt index e4cd23b065..6abd186862 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/home/HomeScreenViewModelTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/home/HomeScreenViewModelTest.kt @@ -40,6 +40,7 @@ import com.anytypeio.anytype.domain.collections.AddObjectToCollection import com.anytypeio.anytype.domain.config.ConfigStorage import com.anytypeio.anytype.domain.config.Gateway import com.anytypeio.anytype.domain.dataview.interactor.CreateDataViewObject +import com.anytypeio.anytype.domain.debugging.Logger import com.anytypeio.anytype.domain.event.interactor.InterceptEvents import com.anytypeio.anytype.domain.launch.GetDefaultObjectType import com.anytypeio.anytype.domain.library.StoreSearchByIdsParams @@ -57,6 +58,8 @@ 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.primitives.FieldParser +import com.anytypeio.anytype.domain.primitives.FieldParserImpl import com.anytypeio.anytype.domain.search.SearchObjects import com.anytypeio.anytype.domain.spaces.ClearLastOpenedSpace import com.anytypeio.anytype.domain.spaces.GetSpaceView @@ -92,7 +95,6 @@ import com.anytypeio.anytype.presentation.widgets.WidgetConfig import com.anytypeio.anytype.presentation.widgets.WidgetDispatchEvent import com.anytypeio.anytype.presentation.widgets.WidgetSessionStateHolder import com.anytypeio.anytype.presentation.widgets.WidgetView -import com.anytypeio.anytype.presentation.widgets.getWidgetObjectName import com.anytypeio.anytype.test_utils.MockDataFactory import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -265,6 +267,11 @@ class HomeScreenViewModelTest { lateinit var vm: HomeScreenViewModel + lateinit var fieldParser: FieldParser + + @Mock + lateinit var logger: Logger + @OptIn(ExperimentalCoroutinesApi::class) private val appCoroutineDispatchers = AppCoroutineDispatchers( io = coroutineTestRule.dispatcher, @@ -301,6 +308,7 @@ class HomeScreenViewModelTest { @Before fun setup() { MockitoAnnotations.openMocks(this) + fieldParser = FieldParserImpl(dateProvider, logger) urlBuilder = UrlBuilder(gateway) stubSpaceManager() userPermissionProvider = UserPermissionProviderStub() @@ -509,7 +517,7 @@ class HomeScreenViewModelTest { elements = emptyList(), isExpanded = true, name = WidgetView.Name.Default( - prettyPrintName = sourceObject.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(sourceObject) ) ) ) @@ -620,7 +628,7 @@ class HomeScreenViewModelTest { WidgetView.Tree( id = widgetBlock.id, name = WidgetView.Name.Default( - prettyPrintName = sourceObject.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(sourceObject) ), source = Widget.Source.Default(sourceObject), elements = listOf( @@ -632,7 +640,7 @@ class HomeScreenViewModelTest { indent = 0, path = widgetBlock.id + "/" + sourceObject.id + "/" + firstLink.id, name = WidgetView.Name.Default( - prettyPrintName = firstLink.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(firstLink) ) ), WidgetView.Tree.Element( @@ -643,7 +651,7 @@ class HomeScreenViewModelTest { indent = 0, path = widgetBlock.id + "/" + sourceObject.id + "/" + secondLink.id, name = WidgetView.Name.Default( - prettyPrintName = secondLink.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(secondLink) ) ) ), @@ -750,7 +758,7 @@ class HomeScreenViewModelTest { WidgetView.SetOfObjects( id = widgetBlock.id, name = WidgetView.Name.Default( - prettyPrintName = sourceObject.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(sourceObject) ), source = Widget.Source.Default(sourceObject), elements = emptyList(), @@ -859,7 +867,7 @@ class HomeScreenViewModelTest { WidgetView.SetOfObjects( id = widgetBlock.id, name = WidgetView.Name.Default( - prettyPrintName = sourceObject.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(sourceObject) ), source = Widget.Source.Default(sourceObject), elements = emptyList(), @@ -1106,7 +1114,7 @@ class HomeScreenViewModelTest { indent = 0, path = favoriteWidgetBlock.id + "/" + favoriteSource.id + "/" + firstLink.id, name = WidgetView.Name.Default( - prettyPrintName = firstLink.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(firstLink) ) ), WidgetView.Tree.Element( @@ -1117,7 +1125,7 @@ class HomeScreenViewModelTest { indent = 0, path = favoriteWidgetBlock.id + "/" + favoriteSource.id + "/" + secondLink.id, name = WidgetView.Name.Default( - prettyPrintName = secondLink.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(secondLink) ) ) ), @@ -1140,7 +1148,7 @@ class HomeScreenViewModelTest { indent = 0, path = recentWidgetBlock.id + "/" + recentSource.id + "/" + firstLink.id, name = WidgetView.Name.Default( - prettyPrintName = firstLink.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(firstLink) ) ), WidgetView.Tree.Element( @@ -1151,7 +1159,7 @@ class HomeScreenViewModelTest { indent = 0, path = recentWidgetBlock.id + "/" + recentSource.id + "/" + secondLink.id, name = WidgetView.Name.Default( - prettyPrintName = secondLink.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(secondLink) ) ) ), @@ -1174,7 +1182,7 @@ class HomeScreenViewModelTest { indent = 0, path = setsWidgetBlock.id + "/" + setsSource.id + "/" + firstLink.id, name = WidgetView.Name.Default( - prettyPrintName = firstLink.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(firstLink) ) ), WidgetView.Tree.Element( @@ -1185,7 +1193,7 @@ class HomeScreenViewModelTest { indent = 0, path = setsWidgetBlock.id + "/" + setsSource.id + "/" + secondLink.id, name = WidgetView.Name.Default( - prettyPrintName = secondLink.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(secondLink) ) ) ), @@ -1278,7 +1286,7 @@ class HomeScreenViewModelTest { id = widgetBlock.id, source = Widget.Source.Default(sourceObject), name = WidgetView.Name.Default( - sourceObject.getWidgetObjectName() + fieldParser.getObjectName(sourceObject) ) ) ) @@ -3034,7 +3042,8 @@ class HomeScreenViewModelTest { container = storelessSubscriptionContainer, manager = spaceManager ), - featureToggles = featureToggles + featureToggles = featureToggles, + fieldParser = fieldParser ) companion object { diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/home/TreeWidgetContainerTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/home/TreeWidgetContainerTest.kt index 2fa14cd57c..76c088f925 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/home/TreeWidgetContainerTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/home/TreeWidgetContainerTest.kt @@ -9,19 +9,21 @@ import com.anytypeio.anytype.core_models.StubObject import com.anytypeio.anytype.core_models.primitives.SpaceId import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers import com.anytypeio.anytype.domain.config.Gateway +import com.anytypeio.anytype.domain.debugging.Logger import com.anytypeio.anytype.domain.library.StoreSearchByIdsParams import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer +import com.anytypeio.anytype.domain.misc.DateProvider import com.anytypeio.anytype.domain.misc.UrlBuilder import com.anytypeio.anytype.domain.objects.ObjectWatcher +import com.anytypeio.anytype.domain.primitives.FieldParser +import com.anytypeio.anytype.domain.primitives.FieldParserImpl import com.anytypeio.anytype.domain.spaces.GetSpaceView import com.anytypeio.anytype.presentation.objects.ObjectIcon -import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider import com.anytypeio.anytype.presentation.util.DefaultCoroutineTestRule import com.anytypeio.anytype.presentation.widgets.TreePath import com.anytypeio.anytype.presentation.widgets.TreeWidgetContainer import com.anytypeio.anytype.presentation.widgets.Widget import com.anytypeio.anytype.presentation.widgets.WidgetView -import com.anytypeio.anytype.presentation.widgets.getWidgetObjectName import com.anytypeio.anytype.test_utils.MockDataFactory import kotlin.test.assertEquals import kotlinx.coroutines.delay @@ -63,6 +65,13 @@ class TreeWidgetContainerTest { private lateinit var urlBuilder: UrlBuilder + lateinit var fieldParser: FieldParser + + @Mock + lateinit var logger: Logger + + @Mock + lateinit var dateProvider: DateProvider private val config = StubConfig() private val workspace = config.spaceView @@ -70,6 +79,7 @@ class TreeWidgetContainerTest { @Before fun setup() { MockitoAnnotations.openMocks(this) + fieldParser = FieldParserImpl(dateProvider, logger) urlBuilder = UrlBuilder(gateway = gateway) } @@ -104,7 +114,8 @@ class TreeWidgetContainerTest { urlBuilder = urlBuilder, isSessionActive = flowOf(true), objectWatcher = objectWatcher, - getSpaceView = getSpaceView + getSpaceView = getSpaceView, + fieldParser = fieldParser ) stubObjectSearch( @@ -180,7 +191,8 @@ class TreeWidgetContainerTest { urlBuilder = urlBuilder, isSessionActive = flowOf(true), objectWatcher = objectWatcher, - getSpaceView = getSpaceView + getSpaceView = getSpaceView, + fieldParser = fieldParser ) stubObjectSearch( @@ -271,7 +283,8 @@ class TreeWidgetContainerTest { urlBuilder = urlBuilder, isSessionActive = flowOf(true), objectWatcher = objectWatcher, - getSpaceView = getSpaceView + getSpaceView = getSpaceView, + fieldParser = fieldParser ) stubObjectSearch( @@ -300,7 +313,7 @@ class TreeWidgetContainerTest { id = widget.id, source = widget.source, name = WidgetView.Name.Default( - (widget.source as Widget.Source.Default).obj.getWidgetObjectName() + fieldParser.getObjectName((widget.source as Widget.Source.Default).obj) ), elements = listOf( WidgetView.Tree.Element( @@ -311,7 +324,7 @@ class TreeWidgetContainerTest { elementIcon = WidgetView.Tree.ElementIcon.Branch(isExpanded = false), objectIcon = ObjectIcon.Empty.Page, name = WidgetView.Name.Default( - prettyPrintName = sourceLinks[0].getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(sourceLinks[0]) ) ), WidgetView.Tree.Element( @@ -322,7 +335,7 @@ class TreeWidgetContainerTest { elementIcon = WidgetView.Tree.ElementIcon.Leaf, objectIcon = ObjectIcon.Empty.Page, name = WidgetView.Name.Default( - prettyPrintName = sourceLinks[1].getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(sourceLinks[1]) ) ), WidgetView.Tree.Element( @@ -333,7 +346,7 @@ class TreeWidgetContainerTest { elementIcon = WidgetView.Tree.ElementIcon.Leaf, objectIcon = ObjectIcon.Empty.Page, name = WidgetView.Name.Default( - prettyPrintName = sourceLinks[2].getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(sourceLinks[2]) ) ) ), @@ -349,7 +362,7 @@ class TreeWidgetContainerTest { id = widget.id, source = widget.source, name = WidgetView.Name.Default( - (widget.source as Widget.Source.Default).obj.getWidgetObjectName() + fieldParser.getObjectName((widget.source as Widget.Source.Default).obj) ), elements = listOf( WidgetView.Tree.Element( @@ -360,7 +373,7 @@ class TreeWidgetContainerTest { elementIcon = WidgetView.Tree.ElementIcon.Branch(isExpanded = true), objectIcon = ObjectIcon.Empty.Page, name = WidgetView.Name.Default( - prettyPrintName = sourceLinks[0].getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(sourceLinks[0]) ) ), WidgetView.Tree.Element( @@ -371,7 +384,7 @@ class TreeWidgetContainerTest { elementIcon = WidgetView.Tree.ElementIcon.Leaf, objectIcon = ObjectIcon.Empty.Page, name = WidgetView.Name.Default( - prettyPrintName = linkA1.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(linkA1) ) ), WidgetView.Tree.Element( @@ -382,7 +395,7 @@ class TreeWidgetContainerTest { elementIcon = WidgetView.Tree.ElementIcon.Leaf, objectIcon = ObjectIcon.Empty.Page, name = WidgetView.Name.Default( - prettyPrintName = linkA2.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(linkA2) ) ), WidgetView.Tree.Element( @@ -393,7 +406,7 @@ class TreeWidgetContainerTest { elementIcon = WidgetView.Tree.ElementIcon.Leaf, objectIcon = ObjectIcon.Empty.Page, name = WidgetView.Name.Default( - prettyPrintName = linkA3.getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(linkA3) ) ), WidgetView.Tree.Element( @@ -404,7 +417,7 @@ class TreeWidgetContainerTest { elementIcon = WidgetView.Tree.ElementIcon.Leaf, objectIcon = ObjectIcon.Empty.Page, name = WidgetView.Name.Default( - prettyPrintName = sourceLinks[1].getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(sourceLinks[1]) ) ), WidgetView.Tree.Element( @@ -415,7 +428,7 @@ class TreeWidgetContainerTest { elementIcon = WidgetView.Tree.ElementIcon.Leaf, objectIcon = ObjectIcon.Empty.Page, name = WidgetView.Name.Default( - prettyPrintName = sourceLinks[2].getWidgetObjectName() + prettyPrintName = fieldParser.getObjectName(sourceLinks[2]) ) ) ), @@ -458,7 +471,8 @@ class TreeWidgetContainerTest { urlBuilder = urlBuilder, isSessionActive = flowOf(true), objectWatcher = objectWatcher, - getSpaceView = getSpaceView + getSpaceView = getSpaceView, + fieldParser = fieldParser ) stubObjectSearch( @@ -521,7 +535,8 @@ class TreeWidgetContainerTest { urlBuilder = urlBuilder, isSessionActive = flowOf(true), objectWatcher = objectWatcher, - getSpaceView = getSpaceView + getSpaceView = getSpaceView, + fieldParser = fieldParser ) stubObjectSearch(