diff --git a/app/src/main/java/com/anytypeio/anytype/di/feature/AuthDI.kt b/app/src/main/java/com/anytypeio/anytype/di/feature/AuthDI.kt index a508af94a4..2ec0b9083c 100644 --- a/app/src/main/java/com/anytypeio/anytype/di/feature/AuthDI.kt +++ b/app/src/main/java/com/anytypeio/anytype/di/feature/AuthDI.kt @@ -236,7 +236,7 @@ object SetupNewAccountModule { @JvmStatic @Provides @PerScreen - fun gradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Impl() + fun gradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Default @JvmStatic @Provides 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 41a4bee7e2..12296621b2 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 @@ -204,7 +204,7 @@ object HomeScreenModule { @JvmStatic @Provides @PerScreen - fun gradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Impl() + fun gradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Default @Module interface Declarations { diff --git a/app/src/main/java/com/anytypeio/anytype/di/feature/onboarding/signup/OnboardingSoulCreationAnimDI.kt b/app/src/main/java/com/anytypeio/anytype/di/feature/onboarding/signup/OnboardingSoulCreationAnimDI.kt index d8ba4c12b5..c746445bc8 100644 --- a/app/src/main/java/com/anytypeio/anytype/di/feature/onboarding/signup/OnboardingSoulCreationAnimDI.kt +++ b/app/src/main/java/com/anytypeio/anytype/di/feature/onboarding/signup/OnboardingSoulCreationAnimDI.kt @@ -54,7 +54,7 @@ object OnboardingSoulCreationAnimModule { @JvmStatic @Provides @SoulCreationAnimScreenScope - fun provideSpaceGradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Impl() + fun provideSpaceGradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Default @Module interface Declarations { diff --git a/app/src/main/java/com/anytypeio/anytype/di/feature/onboarding/signup/OnboardingVoidDI.kt b/app/src/main/java/com/anytypeio/anytype/di/feature/onboarding/signup/OnboardingVoidDI.kt index 1eedafe62e..f9b4e8ba49 100644 --- a/app/src/main/java/com/anytypeio/anytype/di/feature/onboarding/signup/OnboardingVoidDI.kt +++ b/app/src/main/java/com/anytypeio/anytype/di/feature/onboarding/signup/OnboardingVoidDI.kt @@ -49,7 +49,7 @@ object OnboardingVoidModule { @JvmStatic @Provides @PerScreen - fun gradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Impl() + fun gradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Default @JvmStatic @Provides diff --git a/app/src/main/java/com/anytypeio/anytype/di/feature/settings/FilesStorageDI.kt b/app/src/main/java/com/anytypeio/anytype/di/feature/settings/FilesStorageDI.kt index fb00883792..9c4697f4a7 100644 --- a/app/src/main/java/com/anytypeio/anytype/di/feature/settings/FilesStorageDI.kt +++ b/app/src/main/java/com/anytypeio/anytype/di/feature/settings/FilesStorageDI.kt @@ -67,7 +67,7 @@ object FilesStorageModule { @JvmStatic @Provides @PerScreen - fun provideSpaceGradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Impl() + fun provideSpaceGradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Default @JvmStatic @Provides diff --git a/app/src/main/java/com/anytypeio/anytype/di/feature/settings/MainSettingsDi.kt b/app/src/main/java/com/anytypeio/anytype/di/feature/settings/MainSettingsDi.kt index 302b075d54..c4847054cb 100644 --- a/app/src/main/java/com/anytypeio/anytype/di/feature/settings/MainSettingsDi.kt +++ b/app/src/main/java/com/anytypeio/anytype/di/feature/settings/MainSettingsDi.kt @@ -56,7 +56,7 @@ object MainSettingsModule { @JvmStatic @Provides @PerScreen - fun provideSpaceGradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Impl() + fun provideSpaceGradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Default @JvmStatic @Provides diff --git a/app/src/main/java/com/anytypeio/anytype/di/feature/settings/ProfileDI.kt b/app/src/main/java/com/anytypeio/anytype/di/feature/settings/ProfileDI.kt index 06602259f3..737a67099c 100644 --- a/app/src/main/java/com/anytypeio/anytype/di/feature/settings/ProfileDI.kt +++ b/app/src/main/java/com/anytypeio/anytype/di/feature/settings/ProfileDI.kt @@ -62,7 +62,7 @@ object ProfileModule { @Provides @PerScreen - fun provideSpaceGradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Impl() + fun provideSpaceGradientProvider(): SpaceGradientProvider = SpaceGradientProvider.Default @Provides @PerScreen diff --git a/app/src/main/java/com/anytypeio/anytype/ui/widgets/types/Icons.kt b/app/src/main/java/com/anytypeio/anytype/ui/widgets/types/Icons.kt index 9eed49d485..77bf086ac5 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/widgets/types/Icons.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/widgets/types/Icons.kt @@ -29,6 +29,7 @@ import com.anytypeio.anytype.core_models.Url import com.anytypeio.anytype.core_ui.foundation.noRippleClickable import com.anytypeio.anytype.emojifier.Emojifier import com.anytypeio.anytype.presentation.objects.ObjectIcon +import com.anytypeio.anytype.ui_settings.main.GradientComposeView @Composable fun TreeWidgetObjectIcon( @@ -67,6 +68,14 @@ fun TreeWidgetObjectIcon( modifier = modifier.padding(start = paddingStart, end = paddingEnd) ) } + is ObjectIcon.Profile.Gradient -> { + GradientComposeView( + modifier = modifier.padding(start = paddingStart, end = paddingEnd), + from = icon.from, + to = icon.to, + size = 18.dp + ) + } is ObjectIcon.Basic.Emoji -> { UriImage( uri = Emojifier.safeUri(icon.unicode), @@ -127,6 +136,12 @@ fun ListWidgetObjectIcon( when (icon) { is ObjectIcon.Profile.Avatar -> DefaultProfileAvatarIcon(modifier, iconSize, icon) is ObjectIcon.Profile.Image -> defaultProfileIconImage(icon, modifier, iconSize) + is ObjectIcon.Profile.Gradient -> GradientComposeView( + modifier = modifier, + from = icon.from, + to = icon.to, + size = iconSize + ) is ObjectIcon.Basic.Emoji -> DefaultEmojiObjectIcon(modifier, iconSize, icon) is ObjectIcon.Basic.Image -> DefaultObjectImageIcon(icon.hash, modifier, iconSize) is ObjectIcon.Bookmark -> DefaultObjectBookmarkIcon(icon.image, modifier, iconSize) diff --git a/core-models/src/main/java/com/anytypeio/anytype/core_models/Block.kt b/core-models/src/main/java/com/anytypeio/anytype/core_models/Block.kt index 14a13f4933..aebe4228a7 100644 --- a/core-models/src/main/java/com/anytypeio/anytype/core_models/Block.kt +++ b/core-models/src/main/java/com/anytypeio/anytype/core_models/Block.kt @@ -31,6 +31,7 @@ data class Block( val featuredRelations: List? by default val name: String? by default val iconEmoji: String? by default + val iconOption: Double? by default val coverId: String? by default val coverType: Double? by default val iconImage: String? by default diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/holders/other/Title.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/holders/other/Title.kt index 0635b27338..f4d4a90fad 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/holders/other/Title.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/features/editor/holders/other/Title.kt @@ -5,6 +5,9 @@ import android.view.View import android.view.inputmethod.InputMethodManager import android.widget.ImageView import android.widget.TextView +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.unit.dp import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.postDelayed import androidx.core.view.updateLayoutParams @@ -20,6 +23,7 @@ import com.anytypeio.anytype.core_ui.features.editor.BlockViewDiffUtil import com.anytypeio.anytype.core_ui.features.editor.BlockViewHolder import com.anytypeio.anytype.core_ui.features.editor.holders.`interface`.TextHolder import com.anytypeio.anytype.core_ui.tools.DefaultSpannableFactory +import com.anytypeio.anytype.core_ui.widgets.RadialGradientComposeView import com.anytypeio.anytype.core_ui.widgets.text.TextInputWidget import com.anytypeio.anytype.core_utils.ext.dimen import com.anytypeio.anytype.core_utils.ext.gone @@ -381,6 +385,10 @@ sealed class Title(view: View) : BlockViewHolder(view), TextHolder { override val content: TextInputWidget = binding.title override val selectionView: View = itemView + val gradientView : ComposeView get() = binding + .docProfileIconContainer + .findViewById(R.id.gradient) + private val iconText = binding.imageText private var hasImage = false @@ -407,6 +415,7 @@ sealed class Title(view: View) : BlockViewHolder(view), TextHolder { override fun setImage(item: BlockView.Title) { item.image?.let { url -> iconText.text = "" + gradientView.gone() hasImage = true image.visible() Glide @@ -417,8 +426,23 @@ sealed class Title(view: View) : BlockViewHolder(view), TextHolder { .into(image) } ?: apply { hasImage = false - setIconText(item.text) - image.setImageDrawable(null) + if (item is BlockView.Title.Profile && item.spaceGradient != null) { + val gradient = item.spaceGradient + requireNotNull(gradient) + gradientView.visible() + gradientView.setContent { + RadialGradientComposeView( + modifier = Modifier, + from = gradient.from, + to = gradient.to, + size = 0.dp + ) + } + } else { + gradientView.gone() + setIconText(item.text) + image.setImageDrawable(null) + } } } diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/ObjectIconWidget.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/ObjectIconWidget.kt index 14d5258d1b..f09952f1ba 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/ObjectIconWidget.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/ObjectIconWidget.kt @@ -8,6 +8,9 @@ import android.view.LayoutInflater import android.view.View import android.widget.FrameLayout import android.widget.ImageView +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.ViewCompositionStrategy +import androidx.compose.ui.unit.dp import androidx.core.view.updateLayoutParams import com.anytypeio.anytype.core_models.Url import com.anytypeio.anytype.core_ui.R @@ -139,6 +142,7 @@ class ObjectIconWidget @JvmOverloads constructor( is ObjectIcon.Basic.Avatar -> setBasicInitials(icon.name) is ObjectIcon.Profile.Avatar -> setProfileInitials(icon.name) is ObjectIcon.Profile.Image -> setCircularImage(icon.hash) + is ObjectIcon.Profile.Gradient -> setSpaceGradientView(icon) is ObjectIcon.Task -> setCheckbox(icon.isChecked) is ObjectIcon.Bookmark -> setBookmark(icon.image) is ObjectIcon.None -> removeIcon() @@ -149,6 +153,30 @@ class ObjectIconWidget @JvmOverloads constructor( } } + private fun setSpaceGradientView(icon: ObjectIcon.Profile.Gradient) { + with(binding) { + ivCheckbox.gone() + initialContainer.gone() + emojiContainer.gone() + ivBookmark.gone() + ivImage.gone() + ivBookmark.setImageDrawable(null) + ivEmoji.setImageDrawable(null) + } + binding.composeView.visible() + binding.composeView.apply { + setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) + setContent { + RadialGradientComposeView( + modifier = Modifier, + from = icon.from, + to = icon.to, + size = 0.dp + ) + } + } + } + fun setIcon( emoji: String?, image: Url?, @@ -177,6 +205,7 @@ class ObjectIconWidget @JvmOverloads constructor( ivBookmark.setImageDrawable(null) ivBookmark.gone() initialContainer.visible() + composeView.gone() if (initialContainer.background == null) { initialContainer.setBackgroundResource(R.drawable.object_in_list_background_profile_initial) } @@ -195,6 +224,7 @@ class ObjectIconWidget @JvmOverloads constructor( ivBookmark.setImageDrawable(null) ivBookmark.gone() initialContainer.visible() + composeView.gone() if (initialContainer.background == null) { initialContainer.setBackgroundResource(R.drawable.object_in_list_background_basic_initial) } @@ -213,6 +243,7 @@ class ObjectIconWidget @JvmOverloads constructor( ivBookmark.setImageDrawable(null) ivBookmark.gone() emojiContainer.visible() + composeView.gone() } try { Glide @@ -238,6 +269,7 @@ class ObjectIconWidget @JvmOverloads constructor( initialContainer.invisible() ivBookmark.invisible() emojiContainer.invisible() + composeView.gone() } } @@ -251,6 +283,7 @@ class ObjectIconWidget @JvmOverloads constructor( ivBookmark.setImageDrawable(null) ivBookmark.gone() ivImage.setCircularShape() + composeView.gone() if (isImageWithCorners) { ivImage.setStrokeWidthResource(R.dimen.dp_2) ivImage.strokeColor = @@ -277,6 +310,7 @@ class ObjectIconWidget @JvmOverloads constructor( ivBookmark.setImageDrawable(null) ivImage.visible() ivImage.setCorneredShape(imageCornerRadius) + composeView.gone() if (isImageWithCorners) { ivImage.setStrokeWidthResource(R.dimen.dp_2) ivImage.strokeColor = @@ -295,6 +329,7 @@ class ObjectIconWidget @JvmOverloads constructor( fun setImageDrawable(drawable: Drawable) { with(binding) { + composeView.gone() ivCheckbox.invisible() initialContainer.invisible() ivImage.invisible() @@ -307,6 +342,7 @@ class ObjectIconWidget @JvmOverloads constructor( fun setCheckbox(isChecked: Boolean?) { with(binding) { + composeView.gone() ivCheckbox.visible() ivCheckbox.isActivated = isChecked ?: false initialContainer.invisible() @@ -319,6 +355,7 @@ class ObjectIconWidget @JvmOverloads constructor( private fun setBookmark(image: Url) { with(binding) { + composeView.gone() ivCheckbox.invisible() initialContainer.invisible() emojiContainer.invisible() @@ -334,10 +371,12 @@ class ObjectIconWidget @JvmOverloads constructor( private fun removeIcon() { with(binding) { + composeView.gone() ivEmoji.setImageDrawable(null) ivImage.setImageDrawable(null) ivBookmark.setImageDrawable(null) ivCheckbox.invisible() + binding.composeView.gone() } } } \ No newline at end of file diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/RadialGradientComposeView.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/RadialGradientComposeView.kt new file mode 100644 index 0000000000..c53af70b9c --- /dev/null +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/RadialGradientComposeView.kt @@ -0,0 +1,34 @@ +package com.anytypeio.anytype.core_ui.widgets + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.Dp +import androidx.core.graphics.toColorInt + +@Composable +fun RadialGradientComposeView( + modifier: Modifier, + from: String, + to: String, + size: Dp +) { + val gradient = Brush.radialGradient( + colors = listOf( + Color(from.toColorInt()), + Color(to.toColorInt()) + ) + ) + Box( + modifier = modifier + .size(size) + .clip(CircleShape) + .background(gradient) + ) +} \ No newline at end of file diff --git a/core-ui/src/main/res/layout/item_block_title_profile.xml b/core-ui/src/main/res/layout/item_block_title_profile.xml index bfa538afbb..63639024a8 100644 --- a/core-ui/src/main/res/layout/item_block_title_profile.xml +++ b/core-ui/src/main/res/layout/item_block_title_profile.xml @@ -35,6 +35,12 @@ android:layout_height="match_parent" android:layout_margin="4dp" /> + + + + \ No newline at end of file diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt index 3a1c638557..f291fec342 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/EditorViewModel.kt @@ -94,8 +94,8 @@ import com.anytypeio.anytype.presentation.common.Action import com.anytypeio.anytype.presentation.common.Delegator import com.anytypeio.anytype.presentation.common.StateReducer import com.anytypeio.anytype.presentation.common.SupportCommand -import com.anytypeio.anytype.presentation.editor.ControlPanelMachine.Interactor import com.anytypeio.anytype.presentation.editor.ControlPanelMachine.Event.ObjectTypesWidgetEvent +import com.anytypeio.anytype.presentation.editor.ControlPanelMachine.Interactor import com.anytypeio.anytype.presentation.editor.Editor.Restore import com.anytypeio.anytype.presentation.editor.editor.Command import com.anytypeio.anytype.presentation.editor.editor.Intent @@ -228,6 +228,7 @@ import com.anytypeio.anytype.presentation.relations.getObjectRelations import com.anytypeio.anytype.presentation.relations.views import com.anytypeio.anytype.presentation.search.ObjectSearchConstants import com.anytypeio.anytype.presentation.search.ObjectSearchViewModel +import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider import com.anytypeio.anytype.presentation.util.CopyFileStatus import com.anytypeio.anytype.presentation.util.CopyFileToCacheDirectory import com.anytypeio.anytype.presentation.util.Dispatcher @@ -5818,7 +5819,8 @@ class EditorViewModel( val objects = result .toView( urlBuilder = urlBuilder, - objectTypes = storeOfObjectTypes.getAll() + objectTypes = storeOfObjectTypes.getAll(), + gradientProvider = SpaceGradientProvider.Default ) .filter { SupportedLayouts.layouts.contains(it.layout) diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/model/BlockView.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/model/BlockView.kt index a3ad9f88e5..b2e672b597 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/model/BlockView.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/model/BlockView.kt @@ -17,9 +17,9 @@ import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_CHECKBOX import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_CODE_SNIPPET import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_DATA_VIEW_DEFAULT -import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_DATA_VIEW_SOURCE_DELETED import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_DATA_VIEW_EMPTY_DATA import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_DATA_VIEW_EMPTY_SOURCE +import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_DATA_VIEW_SOURCE_DELETED import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_DESCRIPTION import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_DIVIDER_DOTS import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_DIVIDER_LINE @@ -75,6 +75,7 @@ import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER import com.anytypeio.anytype.presentation.objects.ObjectIcon import com.anytypeio.anytype.presentation.objects.appearance.choose.ObjectAppearanceChooseSettingsView import com.anytypeio.anytype.presentation.relations.ObjectRelationView +import com.anytypeio.anytype.presentation.spaces.SpaceIconView /** * UI-models for different types of blocks. @@ -686,7 +687,8 @@ sealed class BlockView : ViewType { override val mode: Mode = Mode.EDIT, override var cursor: Int? = null, override val searchFields: List = emptyList(), - override val hint: String? = null + override val hint: String? = null, + val spaceGradient: SpaceIconView.Gradient? = null ) : Title(), Searchable { override fun getViewType() = HOLDER_PROFILE_TITLE } diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/render/DefaultBlockViewRenderer.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/render/DefaultBlockViewRenderer.kt index d31ea442bd..63cb48cd24 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/render/DefaultBlockViewRenderer.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/render/DefaultBlockViewRenderer.kt @@ -39,6 +39,8 @@ import com.anytypeio.anytype.presentation.relations.ObjectRelationView import com.anytypeio.anytype.presentation.relations.getCover import com.anytypeio.anytype.presentation.relations.objectTypeRelation import com.anytypeio.anytype.presentation.relations.view +import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider +import com.anytypeio.anytype.presentation.spaces.SpaceIconView import javax.inject.Inject import timber.log.Timber import com.anytypeio.anytype.presentation.editor.Editor.Mode as EditorMode @@ -1516,6 +1518,13 @@ class DefaultBlockViewRenderer @Inject constructor( else null }, + spaceGradient = details.details[root.id]?.iconOption?.let { code -> + val gradient = SpaceGradientProvider.Default.get(code) + SpaceIconView.Gradient( + from = gradient.from, + to = gradient.to + ) + }, isFocused = resolveIsFocused(focus, block), cursor = cursor, coverColor = coverContainer.coverColor, 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 1c46069f55..e943d73d20 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 @@ -213,7 +213,8 @@ class HomeScreenViewModel( urlBuilder = urlBuilder, workspace = config.workspace, config = config, - objectWatcher = objectWatcher + objectWatcher = objectWatcher, + spaceGradientProvider = spaceGradientProvider ) is Widget.List -> if (BundledWidgetSourceIds.ids.contains(widget.source.id)) { ListWidgetContainer( @@ -223,6 +224,7 @@ class HomeScreenViewModel( storage = storelessSubscriptionContainer, isWidgetCollapsed = isCollapsed(widget.id), urlBuilder = urlBuilder, + spaceGradientProvider = spaceGradientProvider, isSessionActive = isSessionActive, objectWatcher = objectWatcher, config = config @@ -236,7 +238,8 @@ class HomeScreenViewModel( activeView = observeCurrentWidgetView(widget.id), isWidgetCollapsed = isCollapsed(widget.id), isSessionActive = isSessionActive, - urlBuilder = urlBuilder + urlBuilder = urlBuilder, + gradientProvider = spaceGradientProvider ) } } diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/linking/LinkToObjectOrWebViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/linking/LinkToObjectOrWebViewModel.kt index 1e4e07ac27..5834c53f62 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/linking/LinkToObjectOrWebViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/linking/LinkToObjectOrWebViewModel.kt @@ -21,6 +21,7 @@ import com.anytypeio.anytype.presentation.objects.toLinkToObjectView import com.anytypeio.anytype.presentation.objects.toLinkToView import com.anytypeio.anytype.presentation.search.ObjectSearchConstants import com.anytypeio.anytype.presentation.search.ObjectSearchViewModel +import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow @@ -107,6 +108,7 @@ class LinkToObjectOrWebViewModel( LinkToItemView.Subheading.LinkedTo, obj.toLinkToObjectView( urlBuilder = urlBuilder, + gradientProvider = SpaceGradientProvider.Default, objectTypes = storeOfObjectTypes.getAll() ), LinkToItemView.Subheading.Actions, @@ -127,7 +129,8 @@ class LinkToObjectOrWebViewModel( val objectViews = filteredSearchResponse.toLinkToView( urlBuilder = urlBuilder, - objectTypes = storeOfObjectTypes.getAll() + objectTypes = storeOfObjectTypes.getAll(), + gradientProvider = SpaceGradientProvider.Default ) val views = mutableListOf() if (clipboardUrl != null && userInput.value.isBlank()) { diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/ObjectIcon.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/ObjectIcon.kt index 901472988b..ddae495127 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/ObjectIcon.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/ObjectIcon.kt @@ -5,6 +5,7 @@ import com.anytypeio.anytype.core_models.ObjectType import com.anytypeio.anytype.core_models.ObjectWrapper import com.anytypeio.anytype.core_models.Url import com.anytypeio.anytype.domain.misc.UrlBuilder +import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider sealed class ObjectIcon { object None : ObjectIcon() @@ -17,6 +18,7 @@ sealed class ObjectIcon { sealed class Profile : ObjectIcon() { data class Avatar(val name: String) : Profile() data class Image(val hash: Hash) : Profile() + data class Gradient(val from: String, val to: String) : Profile() } data class Task(val isChecked: Boolean) : ObjectIcon() @@ -30,7 +32,8 @@ sealed class ObjectIcon { obj: ObjectWrapper.Basic, layout: ObjectType.Layout?, builder: UrlBuilder, - objectTypeNoIcon: Boolean = false + objectTypeNoIcon: Boolean = false, + gradientProvider: SpaceGradientProvider = SpaceGradientProvider.Default, ): ObjectIcon { val img = obj.iconImage val emoji = obj.iconEmoji @@ -46,10 +49,18 @@ sealed class ObjectIcon { !emoji.isNullOrBlank() -> Basic.Emoji(unicode = emoji) else -> Basic.Avatar(obj.name.orEmpty()) } - ObjectType.Layout.PROFILE -> if (!img.isNullOrBlank()) { - Profile.Image(hash = builder.thumbnail(img)) - } else { - Profile.Avatar(name = obj.name.orEmpty()) + ObjectType.Layout.PROFILE -> { + val option = obj.iconOption + val gradient = option?.let { code -> + gradientProvider.get(code) + } + if (!img.isNullOrBlank()) { + Profile.Image(hash = builder.thumbnail(img)) + } else if (gradient != null) { + Profile.Gradient(from = gradient.from, to = gradient.to) + } else { + Profile.Avatar(name = obj.name.orEmpty()) + } } ObjectType.Layout.SET, ObjectType.Layout.COLLECTION -> if (!img.isNullOrBlank()) { Basic.Image(hash = builder.thumbnail(img)) diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/ObjectWrapperMapper.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/ObjectWrapperMapper.kt index d8f121c70b..d81608a79a 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/ObjectWrapperMapper.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/ObjectWrapperMapper.kt @@ -15,13 +15,15 @@ import com.anytypeio.anytype.presentation.navigation.DefaultObjectView import com.anytypeio.anytype.presentation.relations.DateParser import com.anytypeio.anytype.presentation.relations.RelationValueView import com.anytypeio.anytype.presentation.sets.filter.CreateFilterView +import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider import com.anytypeio.anytype.presentation.widgets.collection.CollectionView import timber.log.Timber @Deprecated("To be deleted") fun List.toView( urlBuilder: UrlBuilder, - objectTypes: List + objectTypes: List, + gradientProvider: SpaceGradientProvider = SpaceGradientProvider.Default ): List = this.map { obj -> val typeUrl = obj.getProperType() @@ -39,14 +41,16 @@ fun List.toView( icon = ObjectIcon.from( obj = obj, layout = layout, - builder = urlBuilder + builder = urlBuilder, + gradientProvider = gradientProvider ) ) } fun List.toViews( urlBuilder: UrlBuilder, - objectTypes: List + objectTypes: List, + gradientProvider: SpaceGradientProvider = SpaceGradientProvider.Default ): List = map { obj -> val typeUrl = obj.getProperType() val layout = obj.getProperLayout() @@ -60,7 +64,8 @@ fun List.toViews( icon = ObjectIcon.from( obj = obj, layout = layout, - builder = urlBuilder + builder = urlBuilder, + gradientProvider = gradientProvider ), lastModifiedDate = DateParser.parseInMillis(obj.lastModifiedDate) ?: 0L, lastOpenedDate = DateParser.parseInMillis(obj.lastOpenedDate) ?: 0L, @@ -70,6 +75,7 @@ fun List.toViews( fun List.toLibraryViews( urlBuilder: UrlBuilder, + gradientProvider: SpaceGradientProvider = SpaceGradientProvider.Default, ): List = map { obj -> when (val type = obj.getProperType()) { MarketplaceObjectTypeIds.OBJECT_TYPE -> { @@ -79,7 +85,8 @@ fun List.toLibraryViews( icon = ObjectIcon.from( obj = obj, layout = obj.getProperLayout(), - builder = urlBuilder + builder = urlBuilder, + gradientProvider = gradientProvider ), ) } @@ -90,7 +97,8 @@ fun List.toLibraryViews( icon = ObjectIcon.from( obj = obj, layout = obj.getProperLayout(), - builder = urlBuilder + builder = urlBuilder, + gradientProvider = gradientProvider ), sourceObject = obj.map[SOURCE_OBJECT]?.toString(), readOnly = obj.restrictions.contains(ObjectRestriction.DELETE), @@ -126,7 +134,8 @@ fun List.toLibraryViews( fun List.toLinkToView( urlBuilder: UrlBuilder, - objectTypes: List + objectTypes: List, + gradientProvider: SpaceGradientProvider = SpaceGradientProvider.Default, ): List = this.mapIndexed { index, obj -> val typeUrl = obj.getProperType() @@ -140,7 +149,8 @@ fun List.toLinkToView( icon = ObjectIcon.from( obj = obj, layout = layout, - builder = urlBuilder + builder = urlBuilder, + gradientProvider = gradientProvider ), position = index ) @@ -148,6 +158,7 @@ fun List.toLinkToView( fun ObjectWrapper.Basic.toLinkToObjectView( urlBuilder: UrlBuilder, + gradientProvider: SpaceGradientProvider = SpaceGradientProvider.Default, objectTypes: List ): LinkToItemView.LinkedTo.Object { val typeUrl = this.getProperType() @@ -161,7 +172,8 @@ fun ObjectWrapper.Basic.toLinkToObjectView( icon = ObjectIcon.from( obj = this, layout = layout, - builder = urlBuilder + builder = urlBuilder, + gradientProvider = gradientProvider ) ) } @@ -169,7 +181,8 @@ fun ObjectWrapper.Basic.toLinkToObjectView( fun List.toCreateFilterObjectView( ids: List<*>? = null, urlBuilder: UrlBuilder, - objectTypes: List + objectTypes: List, + gradientProvider: SpaceGradientProvider = SpaceGradientProvider.Default, ): List = this.map { obj -> CreateFilterView.Object( @@ -182,7 +195,8 @@ fun List.toCreateFilterObjectView( icon = ObjectIcon.from( obj = obj, layout = obj.getProperLayout(), - builder = urlBuilder + builder = urlBuilder, + gradientProvider = gradientProvider ), isSelected = ids?.contains(obj.id) ?: false ) @@ -191,7 +205,8 @@ fun List.toCreateFilterObjectView( fun List.toRelationObjectValueView( excluded: List, urlBuilder: UrlBuilder, - objectTypes: List + objectTypes: List, + gradientProvider: SpaceGradientProvider = SpaceGradientProvider.Default ): List = this.mapNotNull { obj -> val typeUrl = obj.getProperType() @@ -210,7 +225,8 @@ fun List.toRelationObjectValueView( icon = ObjectIcon.from( obj = obj, layout = layout, - builder = urlBuilder + builder = urlBuilder, + gradientProvider = gradientProvider ), isSelected = false, removable = false diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/menu/ObjectMenuViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/menu/ObjectMenuViewModel.kt index a6ed80ae64..42674d796c 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/menu/ObjectMenuViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/menu/ObjectMenuViewModel.kt @@ -28,7 +28,6 @@ import com.anytypeio.anytype.presentation.common.Delegator import com.anytypeio.anytype.presentation.editor.Editor import com.anytypeio.anytype.presentation.extension.sendAnalyticsCreateTemplateEvent import com.anytypeio.anytype.presentation.extension.sendAnalyticsDefaultTemplateEvent -import com.anytypeio.anytype.presentation.extension.sendAnalyticsCreateTemplateEvent import com.anytypeio.anytype.presentation.objects.ObjectAction import com.anytypeio.anytype.presentation.objects.ObjectIcon import com.anytypeio.anytype.presentation.objects.getProperName @@ -323,7 +322,11 @@ class ObjectMenuViewModel( ObjectWrapper.Basic(storage.details.current().details[type]?.map ?: emptyMap()) return Command.OpenTemplate( template = template, - icon = ObjectIcon.from(objType, objType.layout, urlBuilder), + icon = ObjectIcon.from( + objType, + objType.layout, + urlBuilder + ), typeName = objType.getProperName() ) } 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 9ec362d8be..522becf377 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 @@ -574,6 +574,7 @@ object ObjectSearchConstants { Relations.NAME, Relations.ICON_IMAGE, Relations.ICON_EMOJI, + Relations.ICON_OPTION, Relations.TYPE, Relations.LAYOUT, Relations.IS_ARCHIVED, diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/spaces/SpaceGradientProvider.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/spaces/SpaceGradientProvider.kt index fe4dbfd174..e5a0f8f4af 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/spaces/SpaceGradientProvider.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/spaces/SpaceGradientProvider.kt @@ -1,7 +1,5 @@ package com.anytypeio.anytype.presentation.spaces -import javax.inject.Inject - interface SpaceGradientProvider { fun get(id: Double): Gradient @@ -11,7 +9,7 @@ interface SpaceGradientProvider { */ fun randomId(): Int - class Impl @Inject constructor(): SpaceGradientProvider { + object Default : SpaceGradientProvider { override fun get(id: Double): Gradient { return gradients[id] ?: Gradient("#F6EB7D", "#CBD2FA") 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 38f80e98cc..bd0abea61c 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 @@ -14,6 +14,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.presentation.search.ObjectSearchConstants +import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.combine @@ -29,6 +30,7 @@ class DataViewListWidgetContainer( private val getObject: GetObject, private val storage: StorelessSubscriptionContainer, private val urlBuilder: UrlBuilder, + private val gradientProvider: SpaceGradientProvider, private val activeView: Flow, private val isWidgetCollapsed: Flow, isSessionActive: Flow @@ -76,7 +78,10 @@ class DataViewListWidgetContainer( elements = objects.map { obj -> WidgetView.SetOfObjects.Element( obj = obj, - objectIcon = obj.widgetElementIcon(urlBuilder) + objectIcon = obj.widgetElementIcon( + builder = urlBuilder, + gradientProvider = gradientProvider + ) ) }, isExpanded = true, 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 7ee3067542..d794d99346 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 @@ -16,6 +16,7 @@ import com.anytypeio.anytype.domain.objects.ObjectWatcher import com.anytypeio.anytype.presentation.search.ObjectSearchConstants import com.anytypeio.anytype.presentation.search.ObjectSearchConstants.collectionsSorts import com.anytypeio.anytype.presentation.search.Subscriptions +import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.emptyFlow @@ -30,6 +31,7 @@ class ListWidgetContainer( private val subscription: Id, private val storage: StorelessSubscriptionContainer, private val urlBuilder: UrlBuilder, + private val spaceGradientProvider: SpaceGradientProvider, private val isWidgetCollapsed: Flow, private val objectWatcher: ObjectWatcher, isSessionActive: Flow @@ -98,7 +100,10 @@ class ListWidgetContainer( elements = objects.map { obj -> WidgetView.ListOfObjects.Element( obj = obj, - objectIcon = obj.widgetElementIcon(urlBuilder) + objectIcon = obj.widgetElementIcon( + builder = urlBuilder, + gradientProvider = spaceGradientProvider + ) ) }, isExpanded = true, 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 6087961320..4da8906410 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 @@ -10,6 +10,7 @@ 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.presentation.search.ObjectSearchConstants +import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider import com.anytypeio.anytype.presentation.widgets.WidgetConfig.isValidObject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch @@ -27,6 +28,7 @@ class TreeWidgetContainer( private val config: Config, private val container: StorelessSubscriptionContainer, private val urlBuilder: UrlBuilder, + private val spaceGradientProvider: SpaceGradientProvider, private val expandedBranches: Flow>, private val isWidgetCollapsed: Flow, private val objectWatcher: ObjectWatcher, @@ -217,7 +219,10 @@ class TreeWidgetContainer( expanded = expanded, currentLinkPath = currentLinkPath ), - objectIcon = obj.widgetElementIcon(urlBuilder), + objectIcon = obj.widgetElementIcon( + builder = urlBuilder, + gradientProvider = spaceGradientProvider + ), indent = level, obj = obj, path = path + link 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 e43809ed1a..77512d1726 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 @@ -6,6 +6,7 @@ import com.anytypeio.anytype.core_models.ObjectWrapper import com.anytypeio.anytype.domain.misc.UrlBuilder import com.anytypeio.anytype.presentation.editor.model.Indent import com.anytypeio.anytype.presentation.objects.ObjectIcon +import com.anytypeio.anytype.presentation.spaces.SpaceGradientProvider sealed class WidgetView { @@ -116,9 +117,15 @@ fun ObjectWrapper.Basic.getWidgetObjectName(): String? { } } -fun ObjectWrapper.Basic.widgetElementIcon(builder: UrlBuilder) : ObjectIcon { +fun ObjectWrapper.Basic.widgetElementIcon( + builder: UrlBuilder, + gradientProvider: SpaceGradientProvider +) : ObjectIcon { val img = iconImage val emoji = iconEmoji + val option = iconOption?.let { code -> + gradientProvider.get(code) + } return when (layout) { ObjectType.Layout.BASIC -> when { !img.isNullOrBlank() -> ObjectIcon.Basic.Image(hash = builder.thumbnail(img)) @@ -130,10 +137,17 @@ fun ObjectWrapper.Basic.widgetElementIcon(builder: UrlBuilder) : ObjectIcon { !emoji.isNullOrBlank() -> ObjectIcon.Basic.Emoji(unicode = emoji) else -> ObjectIcon.None } - ObjectType.Layout.PROFILE -> if (!img.isNullOrBlank()) { - ObjectIcon.Profile.Image(hash = builder.thumbnail(img)) - } else { - ObjectIcon.Profile.Avatar(name = name.orEmpty()) + ObjectType.Layout.PROFILE -> { + if (!img.isNullOrBlank()) { + ObjectIcon.Profile.Image(hash = builder.thumbnail(img)) + } else if (option != null) { + ObjectIcon.Profile.Gradient( + from = option.from, + to = option.to + ) + } else { + ObjectIcon.Profile.Avatar(name = name.orEmpty()) + } } ObjectType.Layout.SET, ObjectType.Layout.COLLECTION -> if (!img.isNullOrBlank()) { ObjectIcon.Basic.Image(hash = builder.thumbnail(img)) 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 635e6878b1..741cf2168d 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 @@ -13,6 +13,7 @@ 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.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 @@ -42,6 +43,9 @@ class TreeWidgetContainerTest { @Mock lateinit var gateway: Gateway + @Mock + lateinit var spaceGradientProvider: SpaceGradientProvider + @Mock lateinit var storelessSubscriptionContainer: StorelessSubscriptionContainer @@ -97,7 +101,8 @@ class TreeWidgetContainerTest { workspace = workspace, isSessionActive = flowOf(true), config = config, - objectWatcher = objectWatcher + objectWatcher = objectWatcher, + spaceGradientProvider = spaceGradientProvider ) stubObjectSearch( @@ -167,7 +172,8 @@ class TreeWidgetContainerTest { workspace = workspace, isSessionActive = flowOf(true), config = config, - objectWatcher = objectWatcher + objectWatcher = objectWatcher, + spaceGradientProvider = spaceGradientProvider ) stubObjectSearch( @@ -252,7 +258,8 @@ class TreeWidgetContainerTest { workspace = workspace, isSessionActive = flowOf(true), config = config, - objectWatcher = objectWatcher + objectWatcher = objectWatcher, + spaceGradientProvider = spaceGradientProvider ) stubObjectSearch( @@ -392,7 +399,8 @@ class TreeWidgetContainerTest { workspace = workspace, isSessionActive = flowOf(true), config = config, - objectWatcher = objectWatcher + objectWatcher = objectWatcher, + spaceGradientProvider = spaceGradientProvider ) stubObjectSearch( @@ -449,7 +457,8 @@ class TreeWidgetContainerTest { workspace = workspace, isSessionActive = flowOf(true), config = config, - objectWatcher = objectWatcher + objectWatcher = objectWatcher, + spaceGradientProvider = spaceGradientProvider ) stubObjectSearch( diff --git a/ui-settings/src/main/java/com/anytypeio/anytype/ui_settings/main/MainSettingScreen.kt b/ui-settings/src/main/java/com/anytypeio/anytype/ui_settings/main/MainSettingScreen.kt index c7f4beef8a..b081784bf2 100644 --- a/ui-settings/src/main/java/com/anytypeio/anytype/ui_settings/main/MainSettingScreen.kt +++ b/ui-settings/src/main/java/com/anytypeio/anytype/ui_settings/main/MainSettingScreen.kt @@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.MaterialTheme import androidx.compose.material.Text @@ -24,6 +25,7 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.core.graphics.toColorInt @@ -256,4 +258,25 @@ fun ProfileOption( Arrow() } } +} + +@Composable +fun GradientComposeView( + modifier: Modifier, + from: String, + to: String, + size: Dp +) { + val gradient = Brush.radialGradient( + colors = listOf( + Color(from.toColorInt()), + Color(to.toColorInt()) + ) + ) + Box( + modifier = modifier + .size(size) + .clip(CircleShape) + .background(gradient) + ) } \ No newline at end of file