1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

DROID-3484 Primitives | New mention type: Object Type markup (#2298)

This commit is contained in:
Konstantin Ivanov 2025-04-12 14:53:57 +02:00 committed by GitHub
parent 6fcbe663cd
commit 2c28dbb480
Signed by: github
GPG key ID: B5690EEEBB952194
7 changed files with 112 additions and 38 deletions

View file

@ -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)
}
}
}

View file

@ -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<Int, Int> {
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())
}
}
}
}

View file

@ -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(

View file

@ -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
}

View file

@ -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,

View file

@ -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)
}
}

View file

@ -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(