diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/common/Markup.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/common/Markup.kt index 3c94333d38..ca75e9edd7 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/common/Markup.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/common/Markup.kt @@ -7,6 +7,7 @@ import android.text.SpannableStringBuilder import android.text.style.ClickableSpan import android.view.View import androidx.core.content.ContextCompat +import androidx.core.graphics.drawable.DrawableCompat import com.anytypeio.anytype.core_ui.R import com.anytypeio.anytype.core_ui.extensions.dark import com.anytypeio.anytype.core_ui.extensions.drawable @@ -17,6 +18,7 @@ import com.anytypeio.anytype.core_utils.ext.removeSpans import com.anytypeio.anytype.presentation.editor.editor.Markup import com.anytypeio.anytype.core_models.ThemeColor import com.anytypeio.anytype.core_ui.extensions.disable +import com.anytypeio.anytype.core_ui.widgets.getDrawableAndTintColor import timber.log.Timber fun Markup.toSpannable( @@ -493,6 +495,30 @@ fun Editable.proceedWithSettingMentionSpan( ) setClickableSpan(click, mark) } + is Markup.Mark.Mention.ObjectType -> { + val (drawableRes, tint) = mark.icon.getDrawableAndTintColor(context) + val drawable = ContextCompat.getDrawable(context, drawableRes)?.mutate() + if (drawable != null) { + DrawableCompat.setTint(drawable, tint) + } + val finalDrawable = drawable ?: ContextCompat.getDrawable(context, R.drawable.ic_empty_state_type) + setSpan( + MentionSpan( + onImageResourceReady = onImageReady, + context = context, + imageSize = mentionImageSize, + imagePadding = mentionImagePadding, + param = mark.param, + emoji = null, + placeholder = finalDrawable, + isArchived = false + ), + mark.from, + mark.to, + Markup.MENTION_SPANNABLE_FLAG + ) + setClickableSpan(click, mark) + } } } 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 f31ac87dd4..7541297d53 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 @@ -19,6 +19,7 @@ import com.anytypeio.anytype.core_ui.extensions.drawable import com.anytypeio.anytype.core_ui.extensions.getMimeIcon import com.anytypeio.anytype.core_ui.extensions.setCircularShape import com.anytypeio.anytype.core_ui.extensions.setCorneredShape +import com.anytypeio.anytype.core_ui.widgets.ObjectIconWidget.Companion.DRAWABLE_DIR import com.anytypeio.anytype.core_utils.ext.gone import com.anytypeio.anytype.core_utils.ext.invisible import com.anytypeio.anytype.core_utils.ext.visible @@ -368,41 +369,7 @@ class ObjectIconWidget @JvmOverloads constructor( private fun setTypeIcon(icon: ObjectIcon.TypeIcon) { - //todo next PR - val (resId, tint) = when (icon) { - is ObjectIcon.TypeIcon.Default -> { - val resId = context.resources.getIdentifier( - icon.drawableResId, - DRAWABLE_DIR, - context.packageName - ) - if (resId != 0) { - resId to context.getColor(icon.color.colorRes()) - } else { - 0 to 0 - } - } - - ObjectIcon.TypeIcon.Deleted -> 0 to 0 - is ObjectIcon.TypeIcon.Emoji -> 0 to 0 - is ObjectIcon.TypeIcon.Fallback -> { - val resId = context.resources.getIdentifier( - icon.drawableResId, - DRAWABLE_DIR, - context.packageName - ) - if (resId != 0) { - resId to context.getColor(CustomIconColor.Transparent.colorRes()) - } else { - val defaultFallback = ObjectIcon.TypeIcon.Fallback.DEFAULT - context.resources.getIdentifier( - defaultFallback.drawableResId, - DRAWABLE_DIR, - context.packageName - ) to context.getColor(CustomIconColor.Transparent.colorRes()) - } - } - } + val (resId, tint) = icon.getDrawableAndTintColor(context) with(binding) { ivCheckbox.invisible() @@ -422,3 +389,41 @@ class ObjectIconWidget @JvmOverloads constructor( } } } + +fun TypeIcon.getDrawableAndTintColor(context: Context): Pair { + val icon = this + return when (icon) { + is ObjectIcon.TypeIcon.Default -> { + val resId = context.resources.getIdentifier( + icon.drawableResId, + DRAWABLE_DIR, + context.packageName + ) + if (resId != 0) { + resId to context.getColor(icon.color.colorRes()) + } else { + 0 to 0 + } + } + + ObjectIcon.TypeIcon.Deleted -> 0 to 0 + is ObjectIcon.TypeIcon.Emoji -> 0 to 0 + is ObjectIcon.TypeIcon.Fallback -> { + val resId = context.resources.getIdentifier( + icon.drawableResId, + DRAWABLE_DIR, + context.packageName + ) + if (resId != 0) { + resId to context.getColor(CustomIconColor.Transparent.colorRes()) + } else { + val defaultFallback = ObjectIcon.TypeIcon.Fallback.DEFAULT + context.resources.getIdentifier( + defaultFallback.drawableResId, + DRAWABLE_DIR, + context.packageName + ) to context.getColor(CustomIconColor.Transparent.colorRes()) + } + } + } +} diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/Markup.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/Markup.kt index 1fee6c106a..77171cb8ac 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/Markup.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/Markup.kt @@ -2,6 +2,7 @@ package com.anytypeio.anytype.presentation.editor.editor import android.text.Spannable import com.anytypeio.anytype.core_models.ThemeColor +import com.anytypeio.anytype.presentation.objects.ObjectIcon /** * Classes implementing this interface should support markup rendering. @@ -109,6 +110,13 @@ interface Markup { override val param: String, ) : Mention() + data class ObjectType( + override val from: Int, + override val to: Int, + override val param: String, + val icon: ObjectIcon.TypeIcon + ) : Mention() + sealed class Profile : Mention() { abstract val isArchived: Boolean data class WithImage( diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/ext/ContentTextExt.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/ext/ContentTextExt.kt index e73c6c1594..b00bcea537 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/ext/ContentTextExt.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/ext/ContentTextExt.kt @@ -44,7 +44,7 @@ fun Block.Content.Text.getTextAndMarks( else -> { val obj = details.getObject(mark.param) if (obj != null) { - fieldParser.getObjectName(obj) + fieldParser.getObjectNameOrPluralsForTypes(obj) } else { return@forEach } diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/mention/MentionExt.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/mention/MentionExt.kt index 73f3dde45e..bbca80f37e 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/mention/MentionExt.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/editor/mention/MentionExt.kt @@ -7,6 +7,7 @@ import com.anytypeio.anytype.domain.misc.UrlBuilder import com.anytypeio.anytype.presentation.editor.editor.Markup import com.anytypeio.anytype.presentation.editor.editor.mention.MentionConst.MENTION_PREFIX import com.anytypeio.anytype.presentation.editor.editor.mention.MentionConst.MENTION_TITLE_EMPTY +import com.anytypeio.anytype.presentation.mapper.objectIcon import com.anytypeio.anytype.presentation.navigation.DefaultObjectView fun String.getMentionName(untitled: String): String = if (this.isBlank()) untitled else this @@ -72,6 +73,15 @@ fun Block.Content.Text.Mark.createMentionMarkup( urlBuilder = urlBuilder, isArchived = isArchived ) + ObjectType.Layout.OBJECT_TYPE -> { + val objType = ObjectWrapper.Type(map = obj.map) + Markup.Mark.Mention.ObjectType( + from = range.first, + to = range.last, + param = p, + icon = objType.objectIcon() + ) + } ObjectType.Layout.DATE -> { Markup.Mark.Mention.Date( from = range.first, diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/extension/MarkupExtension.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/extension/MarkupExtension.kt index c4bfc37987..09bc907c5f 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/extension/MarkupExtension.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/extension/MarkupExtension.kt @@ -206,5 +206,6 @@ private fun Markup.Mark.updateRanges(start: Int, length: Int): Markup.Mark { is Markup.Mark.Mention.Profile.WithImage -> copy(from = newFrom, to = newTo) is Markup.Mark.Mention.Profile.WithInitials -> copy(from = newFrom, to = newTo) is Markup.Mark.Mention.Date -> copy(from = newFrom, to = newTo) + is Markup.Mark.Mention.ObjectType -> copy(from = newFrom, to = newTo) } } \ No newline at end of file diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/mention/MentionExtKtTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/mention/MentionExtKtTest.kt index 750307c1e9..8ae26efb63 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/mention/MentionExtKtTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/mention/MentionExtKtTest.kt @@ -9,6 +9,8 @@ import com.anytypeio.anytype.domain.config.Gateway import com.anytypeio.anytype.domain.misc.UrlBuilder import com.anytypeio.anytype.presentation.editor.editor.Markup import com.anytypeio.anytype.presentation.navigation.DefaultObjectView +import com.anytypeio.anytype.presentation.objects.ObjectIcon +import com.anytypeio.anytype.presentation.objects.custom_icon.CustomIconColor import com.anytypeio.anytype.test_utils.MockDataFactory import kotlin.test.Test import kotlin.test.assertEquals @@ -326,14 +328,13 @@ class MentionExtTest { param = MockDataFactory.randomString() ) - ObjectType.Layout.values().iterator().forEach { layout: ObjectType.Layout -> + ObjectType.Layout.entries.iterator().forEach { layout: ObjectType.Layout -> when (layout) { ObjectType.Layout.BASIC -> equalsMentionBase(mark, layout) ObjectType.Layout.PROFILE, ObjectType.Layout.PARTICIPANT -> equalsMentionProfile(mark, layout) ObjectType.Layout.TODO -> equalsMentionTodo(mark, layout) ObjectType.Layout.SET -> equalsMentionNoIcon(mark, layout) ObjectType.Layout.COLLECTION -> equalsMentionNoIcon(mark, layout) - ObjectType.Layout.OBJECT_TYPE -> equalsMentionNoIcon(mark, layout) ObjectType.Layout.RELATION -> equalsMentionNoIcon(mark, layout) ObjectType.Layout.FILE -> equalsMentionNoIcon(mark, layout) ObjectType.Layout.DASHBOARD -> equalsMentionNoIcon(mark, layout) @@ -341,6 +342,7 @@ class MentionExtTest { ObjectType.Layout.NOTE -> equalsMentionNoIcon(mark, layout) ObjectType.Layout.SPACE -> equalsMentionNoIcon(mark, layout) ObjectType.Layout.PDF -> equalsMentionNoIcon(mark, layout) + ObjectType.Layout.OBJECT_TYPE -> equalsMentionObjectType(mark, layout) else -> {} } } @@ -391,6 +393,28 @@ class MentionExtTest { assertEquals(expected, result) } + private fun equalsMentionObjectType(mark: Block.Content.Text.Mark, layout: ObjectType.Layout?) { + val obj = ObjectWrapper.Basic( + mapOf( + Relations.LAYOUT to layout?.code?.toDouble(), + Relations.ICON_NAME to "typeIcon", + Relations.ICON_OPTION to CustomIconColor.Red.iconOption.toDouble() + ) + ) + val result = mark.createMentionMarkup(obj, urlBuilder) + + val expected = Markup.Mark.Mention.ObjectType( + from = mark.range.first, + to = mark.range.last, + param = mark.param!!, + icon = ObjectIcon.TypeIcon.Default( + rawValue = "typeIcon", + color = CustomIconColor.Red + ) + ) + assertEquals(expected, result) + } + private fun equalsMentionProfile(mark: Block.Content.Text.Mark, layout: ObjectType.Layout) { val image = MockDataFactory.randomString() val obj = ObjectWrapper.Basic(