mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-3367 Primitives | Object icons, part 2 (#2184)
This commit is contained in:
parent
b003a9e915
commit
4ce93478a0
48 changed files with 587 additions and 699 deletions
|
@ -199,6 +199,7 @@ dependencies {
|
|||
implementation libs.glide
|
||||
implementation libs.glideCompose
|
||||
implementation libs.coilCompose
|
||||
implementation libs.coilNetwork
|
||||
implementation libs.dagger
|
||||
implementation libs.timber
|
||||
implementation libs.gson
|
||||
|
|
|
@ -2,7 +2,8 @@ package com.anytypeio.anytype.utils
|
|||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestDispatcher
|
||||
import kotlinx.coroutines.test.resetMain
|
||||
import kotlinx.coroutines.test.setMain
|
||||
import org.junit.rules.TestWatcher
|
||||
|
@ -10,7 +11,7 @@ import org.junit.runner.Description
|
|||
|
||||
@ExperimentalCoroutinesApi
|
||||
class CoroutinesTestRule(
|
||||
private val testDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()
|
||||
private val testDispatcher: TestDispatcher = StandardTestDispatcher()
|
||||
) : TestWatcher() {
|
||||
|
||||
override fun starting(description: Description) {
|
||||
|
@ -21,7 +22,6 @@ class CoroutinesTestRule(
|
|||
override fun finished(description: Description) {
|
||||
super.finished(description)
|
||||
Dispatchers.resetMain()
|
||||
testDispatcher.cleanupTestCoroutines()
|
||||
}
|
||||
|
||||
fun advanceTime(millis: Long) {
|
||||
|
|
|
@ -49,7 +49,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.graphics.toColorInt
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
|
|
|
@ -36,7 +36,7 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.core_models.ext.EMPTY_STRING_VALUE
|
||||
import com.anytypeio.anytype.core_ui.extensions.throttledClick
|
||||
|
|
|
@ -56,6 +56,7 @@ dependencies {
|
|||
implementation libs.composeToolingPreview
|
||||
debugImplementation libs.composeTooling
|
||||
implementation libs.coilCompose
|
||||
implementation libs.coilNetwork
|
||||
implementation libs.composeConstraintLayout
|
||||
implementation libs.composeReorderableLegacy
|
||||
|
||||
|
|
|
@ -22,8 +22,7 @@ import androidx.compose.ui.text.font.FontWeight
|
|||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.core.graphics.toColorInt
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_models.SystemColor
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.foundation.noRippleClickable
|
||||
|
|
|
@ -8,6 +8,8 @@ class DateSelectHolder(
|
|||
val binding: ItemSlashWidgetSelectDateBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
init {
|
||||
binding.ivIcon.setIcon(ObjectIcon.Empty.Date)
|
||||
binding.ivIcon.setIcon(
|
||||
ObjectIcon.TypeIcon.Default.DATE
|
||||
)
|
||||
}
|
||||
}
|
|
@ -62,7 +62,7 @@ import androidx.compose.ui.unit.IntOffset
|
|||
import androidx.compose.ui.unit.TextUnit
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_models.ThemeColor
|
||||
|
|
|
@ -144,7 +144,7 @@ class ObjectItemViewHolder(view: View) : ObjectViewHolder(view) {
|
|||
fun bindSelectDateItem() {
|
||||
title.setText(R.string.select_date)
|
||||
subtitle.gone()
|
||||
icon.setIcon(ObjectIcon.Empty.Date)
|
||||
icon.setIcon(ObjectIcon.TypeIcon.Default.DATE)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ import androidx.compose.ui.res.painterResource
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.common.DEFAULT_DISABLED_ALPHA
|
||||
import com.anytypeio.anytype.core_ui.common.DefaultPreviews
|
||||
|
|
|
@ -130,7 +130,7 @@ fun PreviewObjectListItem() {
|
|||
typeName = "Some type",
|
||||
createdBy = "Some user",
|
||||
layout = ObjectType.Layout.BASIC,
|
||||
icon = ObjectIcon.Empty.Page,
|
||||
icon = ObjectIcon.TypeIcon.Default.DEFAULT,
|
||||
isPossibleToDelete = true
|
||||
)
|
||||
)
|
||||
|
|
|
@ -24,7 +24,7 @@ val StubVerticalItems = listOf(
|
|||
typeName = "Page",
|
||||
createdBy = "by Mike Long",
|
||||
layout = ObjectType.Layout.BASIC,
|
||||
icon = ObjectIcon.Empty.Page
|
||||
icon = ObjectIcon.TypeIcon.Default.DEFAULT
|
||||
),
|
||||
UiObjectsListItem.Item(
|
||||
id = "3",
|
||||
|
|
|
@ -202,7 +202,7 @@ fun PreviewObjectItem() {
|
|||
type = "Type",
|
||||
typeName = "Type Name",
|
||||
description = "Description",
|
||||
icon = ObjectIcon.Basic.Emoji("\uD83D\uDCA1", emptyState = ObjectIcon.Empty.Page),
|
||||
icon = ObjectIcon.Basic.Emoji("\uD83D\uDCA1", fallback = ObjectIcon.TypeIcon.Fallback.DEFAULT),
|
||||
space = "space-1"
|
||||
),
|
||||
isSelected = true,
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package com.anytypeio.anytype.core_ui.views.animations
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
|
||||
@Composable
|
||||
fun LoadingIndicator(
|
||||
containerModifier: Modifier = Modifier,
|
||||
containerSize: Dp,
|
||||
colorStart: Color = colorResource(id = R.color.glyph_active),
|
||||
colorEnd: Color = Color.Transparent,
|
||||
withCircleBackground: Boolean = true
|
||||
) {
|
||||
//todo next PR
|
||||
}
|
|
@ -3,7 +3,6 @@ package com.anytypeio.anytype.core_ui.widgets
|
|||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
|
@ -13,20 +12,16 @@ import androidx.compose.ui.layout.ContentScale
|
|||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_models.Url
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.extensions.getMimeIcon
|
||||
import com.anytypeio.anytype.core_ui.foundation.noRippleClickable
|
||||
import com.anytypeio.anytype.core_ui.widgets.objectIcon.AvatarIconView
|
||||
import com.anytypeio.anytype.core_ui.widgets.objectIcon.CustomIconView
|
||||
import com.anytypeio.anytype.core_ui.widgets.objectIcon.BookmarkIconView
|
||||
import com.anytypeio.anytype.core_ui.widgets.objectIcon.DeletedIconView
|
||||
import com.anytypeio.anytype.core_ui.widgets.objectIcon.EmojiIconView
|
||||
import com.anytypeio.anytype.core_ui.widgets.objectIcon.EmptyIconView
|
||||
import com.anytypeio.anytype.core_ui.widgets.objectIcon.ImageIconView
|
||||
import com.anytypeio.anytype.core_ui.widgets.objectIcon.ObjectIconProfile
|
||||
import com.anytypeio.anytype.core_ui.widgets.objectIcon.TypeIconView
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.bumptech.glide.integration.compose.ExperimentalGlideComposeApi
|
||||
import com.bumptech.glide.integration.compose.GlideImage
|
||||
import com.bumptech.glide.integration.compose.placeholder
|
||||
|
||||
@Composable
|
||||
fun ListWidgetObjectIcon(
|
||||
|
@ -37,28 +32,48 @@ fun ListWidgetObjectIcon(
|
|||
backgroundColor: Int = R.color.shape_tertiary
|
||||
) {
|
||||
when (icon) {
|
||||
is ObjectIcon.Profile.Avatar -> {
|
||||
AvatarIconView(
|
||||
is ObjectIcon.Profile -> {
|
||||
ObjectIconProfile(
|
||||
modifier = modifier,
|
||||
iconSize = iconSize,
|
||||
icon = icon
|
||||
)
|
||||
}
|
||||
is ObjectIcon.Profile.Image -> {
|
||||
DefaultProfileIconImage(icon, modifier, iconSize)
|
||||
}
|
||||
|
||||
is ObjectIcon.Basic.Emoji -> {
|
||||
EmojiIconView(icon = icon, backgroundSize = iconSize, modifier = modifier, backgroundColor = backgroundColor)
|
||||
EmojiIconView(
|
||||
icon = icon,
|
||||
backgroundSize = iconSize,
|
||||
modifier = modifier,
|
||||
backgroundColor = backgroundColor
|
||||
)
|
||||
}
|
||||
|
||||
is ObjectIcon.Basic.Image -> {
|
||||
DefaultObjectImageIcon(icon.hash, modifier, iconSize, fallback = icon.emptyState)
|
||||
ImageIconView(
|
||||
icon = icon,
|
||||
backgroundSize = iconSize,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
is ObjectIcon.Bookmark -> {
|
||||
DefaultObjectBookmarkIcon(icon.image, modifier, iconSize)
|
||||
BookmarkIconView(
|
||||
modifier = modifier,
|
||||
icon = icon,
|
||||
backgroundSize = iconSize
|
||||
)
|
||||
}
|
||||
|
||||
is ObjectIcon.Task -> {
|
||||
DefaultTaskObjectIcon(modifier, iconSize, icon, onTaskIconClicked)
|
||||
DefaultTaskObjectIcon(
|
||||
modifier = modifier,
|
||||
iconSize = iconSize,
|
||||
icon = icon,
|
||||
onIconClicked = onTaskIconClicked
|
||||
)
|
||||
}
|
||||
|
||||
is ObjectIcon.File -> {
|
||||
DefaultFileObjectImageIcon(
|
||||
fileName = icon.fileName.orEmpty(),
|
||||
|
@ -68,28 +83,27 @@ fun ListWidgetObjectIcon(
|
|||
extension = icon.extensions
|
||||
)
|
||||
}
|
||||
is ObjectIcon.Checkbox -> {}
|
||||
ObjectIcon.Deleted -> {
|
||||
DeletedIconView(
|
||||
modifier = modifier,
|
||||
backgroundSize = iconSize
|
||||
)
|
||||
}
|
||||
is ObjectIcon.Empty -> {
|
||||
EmptyIconView(
|
||||
modifier = modifier,
|
||||
emptyType = icon,
|
||||
|
||||
is ObjectIcon.TypeIcon ->
|
||||
TypeIconView(
|
||||
icon = icon,
|
||||
backgroundSize = iconSize,
|
||||
modifier = modifier,
|
||||
backgroundColor = backgroundColor
|
||||
)
|
||||
|
||||
is ObjectIcon.Checkbox -> {
|
||||
//do nothing
|
||||
}
|
||||
ObjectIcon.None -> {}
|
||||
is ObjectIcon.ObjectType -> {
|
||||
CustomIconView(
|
||||
icon = icon,
|
||||
modifier = modifier,
|
||||
iconSize = iconSize
|
||||
)
|
||||
|
||||
ObjectIcon.None -> {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,61 +133,6 @@ fun DefaultTaskObjectIcon(
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalGlideComposeApi::class)
|
||||
@Composable
|
||||
fun DefaultObjectImageIcon(
|
||||
url: Url,
|
||||
modifier: Modifier,
|
||||
iconSize: Dp,
|
||||
fallback: ObjectIcon.Empty
|
||||
) {
|
||||
GlideImage(
|
||||
model = url,
|
||||
contentDescription = "Icon from URI",
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = modifier
|
||||
.size(iconSize)
|
||||
.clip(RoundedCornerShape(2.dp)),
|
||||
failure = placeholder(resourceId = imageAsset(fallback)),
|
||||
loading = placeholder(resourceId = R.drawable.ic_icon_loading)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DefaultObjectBookmarkIcon(
|
||||
url: Url,
|
||||
modifier: Modifier,
|
||||
iconSize: Dp
|
||||
) {
|
||||
Box(modifier = modifier.size(iconSize)) {
|
||||
Image(
|
||||
painter = rememberAsyncImagePainter(url),
|
||||
contentDescription = "Icon from URI",
|
||||
modifier = Modifier
|
||||
.align(Alignment.Center)
|
||||
.size(24.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Composable
|
||||
fun DefaultProfileIconImage(
|
||||
icon: ObjectIcon.Profile.Image,
|
||||
modifier: Modifier,
|
||||
iconSize: Dp
|
||||
) {
|
||||
Image(
|
||||
painter = rememberAsyncImagePainter(icon.hash),
|
||||
contentDescription = "Icon from URI",
|
||||
modifier = modifier
|
||||
.size(iconSize)
|
||||
.clip(CircleShape),
|
||||
contentScale = ContentScale.Crop,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DefaultFileObjectImageIcon(
|
||||
fileName: String,
|
||||
|
@ -202,15 +161,4 @@ fun cornerRadius(size: Dp): Dp {
|
|||
in 64.dp..79.dp -> 8.dp
|
||||
else -> 12.dp
|
||||
}
|
||||
}
|
||||
|
||||
fun imageAsset(emptyType: ObjectIcon.Empty): Int {
|
||||
return when (emptyType) {
|
||||
ObjectIcon.Empty.Bookmark -> R.drawable.ic_empty_state_link
|
||||
ObjectIcon.Empty.Chat -> R.drawable.ic_empty_state_chat
|
||||
ObjectIcon.Empty.List -> R.drawable.ic_empty_state_list
|
||||
ObjectIcon.Empty.ObjectType -> R.drawable.ic_empty_state_type
|
||||
ObjectIcon.Empty.Page -> R.drawable.ic_empty_state_page
|
||||
ObjectIcon.Empty.Date -> R.drawable.ic_obj_date_24
|
||||
}
|
||||
}
|
|
@ -151,8 +151,7 @@ class ObjectIconWidget @JvmOverloads constructor(
|
|||
)
|
||||
ObjectIcon.Deleted -> setDeletedIcon()
|
||||
is ObjectIcon.Checkbox -> setCheckbox(icon.isChecked)
|
||||
is ObjectIcon.Empty -> icon.setEmptyIcon()
|
||||
is ObjectIcon.ObjectType -> setCustomIcon(icon)
|
||||
is ObjectIcon.TypeIcon -> setTypeIcon(icon)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -350,8 +349,23 @@ class ObjectIconWidget @JvmOverloads constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun setCustomIcon(icon: ObjectIcon.ObjectType) {
|
||||
val resId = context.resources.getIdentifier(icon.icon.drawableResId, DRAWABLE_DIR, context.packageName)
|
||||
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 -> 0 to 0
|
||||
}
|
||||
|
||||
with(binding) {
|
||||
ivCheckbox.invisible()
|
||||
initialContainer.invisible()
|
||||
|
@ -362,7 +376,6 @@ class ObjectIconWidget @JvmOverloads constructor(
|
|||
}
|
||||
try {
|
||||
if (resId != 0) {
|
||||
val tint = context.getColor(icon.icon.color.colorRes())
|
||||
binding.tvEmojiFallback.gone()
|
||||
binding.ivEmoji.setImageResource(resId)
|
||||
binding.ivEmoji.imageTintList = ColorStateList.valueOf(tint)
|
||||
|
@ -375,37 +388,4 @@ class ObjectIconWidget @JvmOverloads constructor(
|
|||
Timber.w(e, "Error while setting object type icon for")
|
||||
}
|
||||
}
|
||||
|
||||
private fun ObjectIcon.Empty.setEmptyIcon() {
|
||||
val (drawable, containerBackground) = when (this) {
|
||||
ObjectIcon.Empty.Bookmark -> R.drawable.ic_empty_state_link to true
|
||||
ObjectIcon.Empty.Chat -> R.drawable.ic_empty_state_chat to true
|
||||
ObjectIcon.Empty.List -> R.drawable.ic_empty_state_list to true
|
||||
ObjectIcon.Empty.ObjectType -> R.drawable.ic_empty_state_type to true
|
||||
ObjectIcon.Empty.Page -> R.drawable.ic_empty_state_page to true
|
||||
ObjectIcon.Empty.Date -> R.drawable.ic_obj_date_24 to false
|
||||
}
|
||||
val icon = context.drawable(drawable)
|
||||
with(binding) {
|
||||
ivEmoji.setImageDrawable(icon)
|
||||
ivCheckbox.invisible()
|
||||
initialContainer.invisible()
|
||||
ivImage.invisible()
|
||||
ivBookmark.setImageDrawable(null)
|
||||
ivBookmark.gone()
|
||||
if (containerBackground) {
|
||||
emojiContainer.visible()
|
||||
} else {
|
||||
emojiContainer.visible()
|
||||
emojiContainer.setBackgroundResource(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setIvEmojiSize(emojiSize: Int) {
|
||||
binding.ivEmoji.updateLayoutParams<LayoutParams> {
|
||||
this.height = emojiSize
|
||||
this.width = emojiSize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import com.anytypeio.anytype.core_models.primitives.TypeKey
|
|||
import com.anytypeio.anytype.core_ui.common.DefaultPreviews
|
||||
import com.anytypeio.anytype.presentation.editor.cover.CoverColor
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.custom_icon.CustomIcon
|
||||
import com.anytypeio.anytype.presentation.templates.TemplateObjectTypeView
|
||||
import com.anytypeio.anytype.presentation.templates.TemplateView
|
||||
import com.anytypeio.anytype.presentation.templates.TemplateView.Companion.DEFAULT_TEMPLATE_ID_BLANK
|
||||
|
@ -53,11 +52,7 @@ fun TypeTemplatesWidgetPreview() {
|
|||
type = ObjectWrapper.Type(
|
||||
map = mapOf(Relations.ID to "123", Relations.NAME to "Page"),
|
||||
),
|
||||
icon = ObjectIcon.ObjectType(
|
||||
icon = CustomIcon(
|
||||
rawValue = "batteryCharging"
|
||||
)
|
||||
)
|
||||
icon = ObjectIcon.TypeIcon.Default.DEFAULT
|
||||
)
|
||||
),
|
||||
viewerId = "",
|
||||
|
|
|
@ -78,7 +78,7 @@ import androidx.compose.ui.unit.IntOffset
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.em
|
||||
import androidx.compose.ui.unit.sp
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.anytypeio.anytype.core_ui.widgets.objectIcon
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.size
|
||||
|
@ -7,16 +8,22 @@ import androidx.compose.foundation.shape.CircleShape
|
|||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.colorResource
|
||||
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 coil3.compose.AsyncImagePainter
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.common.DefaultPreviews
|
||||
import com.anytypeio.anytype.core_ui.views.AvatarTitle
|
||||
import com.anytypeio.anytype.core_ui.views.animations.LoadingIndicator
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
|
||||
|
||||
|
@ -24,7 +31,35 @@ val avatarBackgroundColor = R.color.shape_tertiary
|
|||
val avatarTextColor = R.color.glyph_active
|
||||
|
||||
@Composable
|
||||
fun AvatarIconView(
|
||||
fun ObjectIconProfile(
|
||||
modifier: Modifier,
|
||||
iconSize: Dp,
|
||||
icon: ObjectIcon.Profile,
|
||||
isCircleShape: Boolean = true
|
||||
) {
|
||||
when (icon) {
|
||||
is ObjectIcon.Profile.Avatar -> {
|
||||
ProfileAvatarView(
|
||||
modifier = modifier,
|
||||
iconSize = iconSize,
|
||||
icon = icon,
|
||||
isCircleShape = isCircleShape
|
||||
)
|
||||
}
|
||||
|
||||
is ObjectIcon.Profile.Image -> {
|
||||
ProfileImageView(
|
||||
modifier = modifier,
|
||||
iconSize = iconSize,
|
||||
icon = icon
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ProfileAvatarView(
|
||||
modifier: Modifier,
|
||||
iconSize: Dp,
|
||||
icon: ObjectIcon.Profile.Avatar,
|
||||
|
@ -58,6 +93,44 @@ fun AvatarIconView(
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ProfileImageView(
|
||||
icon: ObjectIcon.Profile.Image,
|
||||
modifier: Modifier,
|
||||
iconSize: Dp
|
||||
) {
|
||||
val painter = rememberAsyncImagePainter(icon.hash)
|
||||
val state by painter.state.collectAsState()
|
||||
|
||||
when (state) {
|
||||
AsyncImagePainter.State.Empty,
|
||||
is AsyncImagePainter.State.Loading -> {
|
||||
LoadingIndicator(
|
||||
containerSize = iconSize
|
||||
)
|
||||
}
|
||||
|
||||
is AsyncImagePainter.State.Error -> {
|
||||
ProfileAvatarView(
|
||||
modifier = modifier,
|
||||
iconSize = iconSize,
|
||||
icon = ObjectIcon.Profile.Avatar(name = icon.name)
|
||||
)
|
||||
}
|
||||
|
||||
is AsyncImagePainter.State.Success -> {
|
||||
Image(
|
||||
painter = painter,
|
||||
contentDescription = "Icon from URI",
|
||||
modifier = modifier
|
||||
.size(iconSize)
|
||||
.clip(CircleShape),
|
||||
contentScale = ContentScale.Crop,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAvatarIconParams(size: Dp): Pair<Int, Int> {
|
||||
return when (size) {
|
||||
in 0.dp..16.dp -> 2 to 11
|
||||
|
@ -71,44 +144,4 @@ private fun getAvatarIconParams(size: Dp): Pair<Int, Int> {
|
|||
in 81.dp..96.dp -> 12 to 64
|
||||
else -> 12 to 64
|
||||
}
|
||||
}
|
||||
|
||||
@DefaultPreviews
|
||||
@Composable
|
||||
fun Avatar20IconViewPreview() {
|
||||
AvatarIconView(
|
||||
iconSize = 20.dp,
|
||||
icon = ObjectIcon.Profile.Avatar("John Doe"),
|
||||
modifier = Modifier
|
||||
)
|
||||
}
|
||||
|
||||
@DefaultPreviews
|
||||
@Composable
|
||||
fun Avatar32IconViewPreview() {
|
||||
AvatarIconView(
|
||||
iconSize = 32.dp,
|
||||
icon = ObjectIcon.Profile.Avatar("John Doe"),
|
||||
modifier = Modifier
|
||||
)
|
||||
}
|
||||
|
||||
@DefaultPreviews
|
||||
@Composable
|
||||
fun Avatar48IconViewPreview() {
|
||||
AvatarIconView(
|
||||
iconSize = 48.dp,
|
||||
icon = ObjectIcon.Profile.Avatar("John Doe"),
|
||||
modifier = Modifier
|
||||
)
|
||||
}
|
||||
|
||||
@DefaultPreviews
|
||||
@Composable
|
||||
fun Avatar64IconViewPreview() {
|
||||
AvatarIconView(
|
||||
iconSize = 64.dp,
|
||||
icon = ObjectIcon.Profile.Avatar("John Doe"),
|
||||
modifier = Modifier
|
||||
)
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.anytypeio.anytype.core_ui.widgets.objectIcon
|
||||
|
||||
import androidx.compose.animation.Crossfade
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import coil3.compose.AsyncImagePainter
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_ui.views.animations.LoadingIndicator
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
|
||||
@Composable
|
||||
fun BookmarkIconView(
|
||||
modifier: Modifier = Modifier,
|
||||
icon: ObjectIcon.Bookmark,
|
||||
backgroundSize: Dp,
|
||||
) {
|
||||
|
||||
val painter = rememberAsyncImagePainter(model = icon.image)
|
||||
val painterState by painter.state.collectAsState()
|
||||
|
||||
Crossfade(targetState = painterState) { state ->
|
||||
when (state) {
|
||||
AsyncImagePainter.State.Empty,
|
||||
is AsyncImagePainter.State.Loading -> {
|
||||
LoadingIndicator(containerSize = backgroundSize)
|
||||
}
|
||||
is AsyncImagePainter.State.Error -> {
|
||||
TypeIconView(
|
||||
modifier = modifier,
|
||||
icon = icon.fallback,
|
||||
backgroundSize = backgroundSize
|
||||
)
|
||||
}
|
||||
is AsyncImagePainter.State.Success -> {
|
||||
Image(
|
||||
painter = painter,
|
||||
contentDescription = "Icon from URI",
|
||||
modifier = modifier
|
||||
.size(backgroundSize)
|
||||
.clip(CircleShape),
|
||||
contentScale = ContentScale.Crop,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
package com.anytypeio.anytype.core_ui.widgets.objectIcon
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.anytypeio.anytype.core_ui.common.DefaultPreviews
|
||||
import com.anytypeio.anytype.core_ui.extensions.colorRes
|
||||
import com.anytypeio.anytype.core_ui.widgets.objectIcon.custom_icons.CustomIcons
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.custom_icon.CustomIcon
|
||||
import com.anytypeio.anytype.presentation.objects.custom_icon.CustomIconColor
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
|
||||
@Composable
|
||||
fun CustomIconView(
|
||||
modifier: Modifier = Modifier,
|
||||
icon: ObjectIcon.ObjectType,
|
||||
iconSize: Dp
|
||||
) {
|
||||
val tint = colorResource(id = icon.icon.color.colorRes())
|
||||
|
||||
val imageVector = CustomIcons.getImageVector(icon.icon)
|
||||
|
||||
Box(modifier = modifier) {
|
||||
if (imageVector != null) {
|
||||
Image(
|
||||
modifier = Modifier.size(iconSize),
|
||||
imageVector = imageVector,
|
||||
contentDescription = "Object Type icon",
|
||||
colorFilter = ColorFilter.tint(tint),
|
||||
)
|
||||
} else {
|
||||
Image(
|
||||
modifier = Modifier.size(iconSize),
|
||||
painter = painterResource(id = R.drawable.ic_empty_state_page),
|
||||
contentDescription = "Object Type icon",
|
||||
colorFilter = ColorFilter.tint(tint),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@DefaultPreviews
|
||||
fun CustomIconViewPreview() {
|
||||
CustomIconView(
|
||||
icon = ObjectIcon.ObjectType(
|
||||
icon = CustomIcon(
|
||||
rawValue = "batteryCharging",
|
||||
color = CustomIconColor.Yellow
|
||||
),
|
||||
),
|
||||
modifier = Modifier,
|
||||
iconSize = 18.dp
|
||||
)
|
||||
}
|
|
@ -9,14 +9,11 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.common.DefaultPreviews
|
||||
import com.anytypeio.anytype.core_ui.widgets.cornerRadius
|
||||
import com.anytypeio.anytype.core_ui.widgets.imageAsset
|
||||
import com.anytypeio.anytype.emojifier.Emojifier
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
|
||||
|
@ -40,38 +37,30 @@ fun EmojiIconView(
|
|||
height = backgroundSize * imageMultiplier
|
||||
)
|
||||
} else {
|
||||
modifier.size(backgroundSize) to Modifier
|
||||
modifier.size(backgroundSize) to Modifier.size(
|
||||
width = backgroundSize * imageMultiplier,
|
||||
height = backgroundSize * imageMultiplier
|
||||
)
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = containerModifier,
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
val emoji = Emojifier.safeUri(icon.unicode)
|
||||
|
||||
val emoji = Emojifier.safeUri(icon.unicode)
|
||||
if (emoji != Emojifier.Config.EMPTY_URI) {
|
||||
if (emoji != Emojifier.Config.EMPTY_URI) {
|
||||
Box(
|
||||
modifier = containerModifier,
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Image(
|
||||
painter = rememberAsyncImagePainter(emoji),
|
||||
contentDescription = "Icon from URI",
|
||||
contentDescription = "Emoji object icon",
|
||||
modifier = iconModifier
|
||||
)
|
||||
} else {
|
||||
val imageAsset = imageAsset(icon.emptyState)
|
||||
Image(
|
||||
painter = painterResource(id = imageAsset),
|
||||
contentDescription = "Empty Object Icon",
|
||||
modifier = iconModifier
|
||||
)
|
||||
|
||||
}
|
||||
} else {
|
||||
TypeIconView(
|
||||
modifier = modifier,
|
||||
icon = icon.fallback,
|
||||
backgroundSize = backgroundSize
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@DefaultPreviews
|
||||
@Composable
|
||||
fun Emoji20ObjectIconViewPreview() {
|
||||
EmojiIconView(
|
||||
icon = ObjectIcon.Basic.Emoji("😀", ObjectIcon.Empty.Page),
|
||||
backgroundSize = 20.dp
|
||||
)
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
package com.anytypeio.anytype.core_ui.widgets.objectIcon
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.common.DefaultPreviews
|
||||
import com.anytypeio.anytype.core_ui.widgets.cornerRadius
|
||||
import com.anytypeio.anytype.core_ui.widgets.imageAsset
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
|
||||
@Composable
|
||||
fun EmptyIconView(
|
||||
modifier: Modifier = Modifier,
|
||||
backgroundSize: Dp,
|
||||
emptyType: ObjectIcon.Empty,
|
||||
iconWithoutBackgroundMaxSize: Dp = 20.dp,
|
||||
imageMultiplier: Float = 0.625f,
|
||||
backgroundColor: Int = R.color.shape_tertiary
|
||||
) {
|
||||
val (containerModifier, iconModifier) = if (backgroundSize > iconWithoutBackgroundMaxSize) {
|
||||
modifier
|
||||
.size(backgroundSize)
|
||||
.background(
|
||||
color = colorResource(backgroundColor),
|
||||
shape = RoundedCornerShape(size = cornerRadius(backgroundSize))
|
||||
) to Modifier.size(
|
||||
width = backgroundSize * imageMultiplier,
|
||||
height = backgroundSize * imageMultiplier
|
||||
)
|
||||
} else {
|
||||
modifier.size(backgroundSize) to Modifier
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = containerModifier,
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
|
||||
val imageAsset = imageAsset(emptyType)
|
||||
|
||||
Image(
|
||||
painter = painterResource(id = imageAsset),
|
||||
contentDescription = "Empty Object Icon",
|
||||
modifier = iconModifier
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@DefaultPreviews
|
||||
@Composable
|
||||
fun Empty20ObjectIconViewPreview() {
|
||||
EmptyIconView(
|
||||
emptyType = ObjectIcon.Empty.Page,
|
||||
backgroundSize = 20.dp,
|
||||
)
|
||||
}
|
||||
|
||||
@DefaultPreviews
|
||||
@Composable
|
||||
fun Empty32ObjectIconViewPreview() {
|
||||
EmptyIconView(
|
||||
emptyType = ObjectIcon.Empty.Page,
|
||||
backgroundSize = 32.dp,
|
||||
)
|
||||
}
|
||||
|
||||
@DefaultPreviews
|
||||
@Composable
|
||||
fun Empty48ObjectIconViewPreview() {
|
||||
EmptyIconView(
|
||||
emptyType = ObjectIcon.Empty.Page,
|
||||
backgroundSize = 48.dp
|
||||
)
|
||||
}
|
||||
|
||||
@DefaultPreviews
|
||||
@Composable
|
||||
fun Empty64ObjectIconViewPreview() {
|
||||
EmptyIconView(
|
||||
emptyType = ObjectIcon.Empty.Page,
|
||||
backgroundSize = 64.dp
|
||||
)
|
||||
}
|
||||
|
||||
@DefaultPreviews
|
||||
@Composable
|
||||
fun Empty112ObjectIconViewPreview() {
|
||||
EmptyIconView(
|
||||
emptyType = ObjectIcon.Empty.Page,
|
||||
backgroundSize = 112.dp
|
||||
)
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package com.anytypeio.anytype.core_ui.widgets.objectIcon
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import coil3.compose.AsyncImagePainter
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_ui.views.animations.LoadingIndicator
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.bumptech.glide.integration.compose.ExperimentalGlideComposeApi
|
||||
|
||||
@OptIn(ExperimentalGlideComposeApi::class)
|
||||
@Composable
|
||||
fun ImageIconView(
|
||||
modifier: Modifier = Modifier,
|
||||
icon: ObjectIcon.Basic.Image,
|
||||
backgroundSize: Dp
|
||||
) {
|
||||
|
||||
val painter = rememberAsyncImagePainter(icon.hash)
|
||||
val state by painter.state.collectAsState()
|
||||
|
||||
when (state) {
|
||||
AsyncImagePainter.State.Empty,
|
||||
is AsyncImagePainter.State.Loading -> {
|
||||
LoadingIndicator(
|
||||
containerSize = backgroundSize
|
||||
)
|
||||
}
|
||||
|
||||
is AsyncImagePainter.State.Error -> {
|
||||
TypeIconView(
|
||||
modifier = modifier,
|
||||
icon = icon.fallback,
|
||||
backgroundSize = backgroundSize
|
||||
)
|
||||
}
|
||||
|
||||
is AsyncImagePainter.State.Success -> {
|
||||
Image(
|
||||
painter = painter,
|
||||
contentDescription = "Icon from URI",
|
||||
modifier = modifier
|
||||
.size(backgroundSize)
|
||||
.clip(CircleShape),
|
||||
contentScale = ContentScale.Crop,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.anytypeio.anytype.core_ui.widgets.objectIcon
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
|
||||
@Composable
|
||||
fun TypeIconView(
|
||||
modifier: Modifier = Modifier,
|
||||
icon: ObjectIcon.TypeIcon,
|
||||
backgroundSize: Dp,
|
||||
iconWithoutBackgroundMaxSize: Dp = 20.dp,
|
||||
backgroundColor: Int = R.color.shape_tertiary
|
||||
) {
|
||||
//todo next PR
|
||||
}
|
|
@ -1,14 +1,9 @@
|
|||
package com.anytypeio.anytype.core_ui.widgets.objectIcon.custom_icons
|
||||
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import com.anytypeio.anytype.presentation.objects.custom_icon.CustomIcon
|
||||
|
||||
object CustomIcons {
|
||||
|
||||
fun getImageVector(icon: CustomIcon): ImageVector? {
|
||||
return iconsMap[icon.rawValue]
|
||||
}
|
||||
|
||||
fun getImageVector(name: String): ImageVector? {
|
||||
return iconsMap[name]
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ 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 coil.compose.rememberAsyncImagePainter
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_ui.common.DefaultPreviews
|
||||
import com.anytypeio.anytype.core_ui.foundation.noRippleClickable
|
||||
import com.anytypeio.anytype.feature_chats.R
|
||||
|
|
|
@ -50,8 +50,9 @@ import androidx.compose.ui.text.withStyle
|
|||
import androidx.compose.ui.unit.DpOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import coil.compose.AsyncImage
|
||||
import coil.request.ImageRequest
|
||||
import coil3.compose.AsyncImage
|
||||
import coil3.request.ImageRequest
|
||||
import coil3.request.crossfade
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_ui.foundation.AlertConfig
|
||||
import com.anytypeio.anytype.core_ui.foundation.BUTTON_SECONDARY
|
||||
|
|
|
@ -671,7 +671,7 @@ fun ItemDropDownMenu(
|
|||
fun PreviewTypeFieldsMainScreen() {
|
||||
FieldsMainScreen(
|
||||
uiTitleState = UiTitleState(title = "Page", isEditable = false),
|
||||
uiIconState = UiIconState(icon = ObjectIcon.Empty.ObjectType, isEditable = false),
|
||||
uiIconState = UiIconState(icon = ObjectIcon.TypeIcon.Default.DEFAULT, isEditable = false),
|
||||
uiFieldsListState = UiFieldsListState(
|
||||
items = listOf(
|
||||
UiFieldsListItem.Section.Header(),
|
||||
|
|
|
@ -238,7 +238,7 @@ fun ObjectTypeMainScreenPreview() {
|
|||
)
|
||||
),
|
||||
uiSyncStatusState = SyncStatusWidgetState.Hidden,
|
||||
uiIconState = UiIconState(icon = ObjectIcon.Empty.Page, isEditable = true),
|
||||
uiIconState = UiIconState(icon = ObjectIcon.TypeIcon.Default.DEFAULT, isEditable = true),
|
||||
uiTitleState = UiTitleState(title = "title", isEditable = true),
|
||||
uiFieldsButtonState = UiFieldsButtonState.Visible(4),
|
||||
uiLayoutButtonState = UiLayoutButtonState.Visible(layout = ObjectType.Layout.VIDEO),
|
||||
|
|
|
@ -50,7 +50,7 @@ import androidx.compose.ui.text.input.VisualTransformation
|
|||
import androidx.compose.ui.unit.DpOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_ui.foundation.Divider
|
||||
import com.anytypeio.anytype.core_ui.foundation.Dragger
|
||||
import com.anytypeio.anytype.core_ui.foundation.Option
|
||||
|
|
|
@ -33,7 +33,7 @@ fun NewSpaceSettingsScreenPreview() {
|
|||
UiSpaceSettingsItem.DefaultObjectType(
|
||||
id = "some id",
|
||||
name = "Taskwithveryverlylongname",
|
||||
icon = ObjectIcon.Empty.ObjectType
|
||||
icon = ObjectIcon.TypeIcon.Default.DEFAULT,
|
||||
),
|
||||
UiSpaceSettingsItem.Spacer(height = 8),
|
||||
UiSpaceSettingsItem.Wallpapers(null),
|
||||
|
|
|
@ -43,7 +43,7 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.AsyncImage
|
||||
import coil3.compose.AsyncImage
|
||||
import com.anytypeio.anytype.core_models.ManifestInfo
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.views.ButtonPrimaryLoading
|
||||
|
|
|
@ -32,7 +32,7 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.graphics.toColorInt
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import coil3.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.common.DefaultPreviews
|
||||
|
|
|
@ -61,7 +61,7 @@ timberVersion = '5.0.1'
|
|||
roomVersion = '2.6.1'
|
||||
dataStoreVersion = '1.1.3'
|
||||
amplitudeVersion = '3.35.1'
|
||||
coilComposeVersion = '2.6.0'
|
||||
coilComposeVersion = '3.1.0'
|
||||
sentryVersion = '7.13.0'
|
||||
|
||||
composeQrCodeVersion = '1.0.1'
|
||||
|
@ -98,7 +98,8 @@ gsonWire = { module = "com.squareup.wire:wire-gson-support", version.ref = "wire
|
|||
glide = { module = "com.github.bumptech.glide:glide", version.ref = "glideVersion" }
|
||||
glideCompiler = { module = "com.github.bumptech.glide:compiler", version.ref = "glideVersion" }
|
||||
glideCompose = { module = "com.github.bumptech.glide:compose", version.ref = "glideComposeVersion" }
|
||||
coilCompose = { module = "io.coil-kt:coil-compose", version.ref = "coilComposeVersion" }
|
||||
coilCompose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coilComposeVersion" }
|
||||
coilNetwork = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coilComposeVersion" }
|
||||
mockitoKotlin = { module = "org.mockito.kotlin:mockito-kotlin", version.ref = "mockitoKotlinVersion" }
|
||||
junit = { module = "junit:junit", version.ref = "junitVersion" }
|
||||
androidJUnit = { module = "androidx.test.ext:junit", version.ref = "androidJunitVersion" }
|
||||
|
|
|
@ -1141,16 +1141,13 @@ class DefaultBlockViewRenderer @Inject constructor(
|
|||
val icon = when {
|
||||
!iconImage.isNullOrBlank() ->
|
||||
ObjectIcon.Basic.Image(
|
||||
hash = urlBuilder.thumbnail(iconImage),
|
||||
emptyState = ObjectIcon.Empty.Page
|
||||
hash = urlBuilder.thumbnail(iconImage)
|
||||
)
|
||||
!iconEmoji.isNullOrBlank() -> ObjectIcon.Basic.Emoji(
|
||||
unicode = iconEmoji,
|
||||
emptyState = ObjectIcon.Empty.Page
|
||||
)
|
||||
else -> ObjectIcon.Basic.Emoji(
|
||||
unicode = "💡",
|
||||
emptyState = ObjectIcon.Empty.Page
|
||||
)
|
||||
}
|
||||
return BlockView.Text.Callout(
|
||||
|
|
|
@ -5,200 +5,142 @@ import com.anytypeio.anytype.core_models.ObjectWrapper
|
|||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon.Basic
|
||||
import com.anytypeio.anytype.core_models.SupportedLayouts
|
||||
import com.anytypeio.anytype.presentation.objects.custom_icon.CustomIcon
|
||||
import com.anytypeio.anytype.presentation.objects.custom_icon.CustomIconColor
|
||||
|
||||
fun ObjectWrapper.Basic.objectIcon(builder: UrlBuilder, objType: ObjectWrapper.Type? = null): ObjectIcon {
|
||||
fun ObjectWrapper.Basic.objectIcon(
|
||||
builder: UrlBuilder,
|
||||
objType: ObjectWrapper.Type?
|
||||
): ObjectIcon {
|
||||
|
||||
if (isDeleted == true) {
|
||||
val obj = this
|
||||
|
||||
if (obj.isDeleted == true) {
|
||||
return ObjectIcon.Deleted
|
||||
}
|
||||
|
||||
val objectIcon = layout?.icon(
|
||||
image = iconImage,
|
||||
emoji = iconEmoji,
|
||||
builder = builder,
|
||||
name = name.orEmpty(),
|
||||
iconName = iconName,
|
||||
iconOption = iconOption?.toInt()
|
||||
)
|
||||
val objImage = obj.iconImage
|
||||
val objEmoji = obj.iconEmoji
|
||||
val objName = obj.name.orEmpty()
|
||||
|
||||
if (objectIcon != null) {
|
||||
return objectIcon
|
||||
}
|
||||
|
||||
if (SupportedLayouts.fileLayouts.contains(layout)) {
|
||||
return fileIcon(
|
||||
mime = fileMimeType,
|
||||
name = name,
|
||||
extensions = fileExt
|
||||
)
|
||||
}
|
||||
|
||||
if (layout == ObjectType.Layout.TODO) {
|
||||
return taskIcon(isChecked = done == true)
|
||||
}
|
||||
|
||||
return layout.emptyType()
|
||||
}
|
||||
|
||||
fun ObjectWrapper.Type.objectIcon(builder: UrlBuilder): ObjectIcon {
|
||||
|
||||
if (isDeleted == true) {
|
||||
return ObjectIcon.Deleted
|
||||
}
|
||||
|
||||
val objectIcon = layout?.icon(
|
||||
image = null,
|
||||
emoji = iconEmoji,
|
||||
builder = builder,
|
||||
name = name.orEmpty(),
|
||||
iconName = iconName,
|
||||
iconOption = iconOption?.toInt()
|
||||
)
|
||||
|
||||
if (objectIcon != null) {
|
||||
return objectIcon
|
||||
}
|
||||
|
||||
return layout.emptyType()
|
||||
}
|
||||
|
||||
fun ObjectWrapper.Type.objectIcon(): ObjectIcon {
|
||||
//todo next pr
|
||||
return ObjectIcon.None
|
||||
}
|
||||
|
||||
fun ObjectType.Layout?.emptyType(): ObjectIcon.Empty {
|
||||
if (this == null) {
|
||||
return ObjectIcon.Empty.Page
|
||||
}
|
||||
return when (this) {
|
||||
ObjectType.Layout.SET, ObjectType.Layout.COLLECTION -> ObjectIcon.Empty.List
|
||||
ObjectType.Layout.OBJECT_TYPE -> ObjectIcon.Empty.ObjectType
|
||||
ObjectType.Layout.BOOKMARK -> ObjectIcon.Empty.Bookmark
|
||||
ObjectType.Layout.CHAT, ObjectType.Layout.CHAT_DERIVED -> ObjectIcon.Empty.Chat
|
||||
ObjectType.Layout.DATE -> ObjectIcon.Empty.Date
|
||||
else -> ObjectIcon.Empty.Page
|
||||
}
|
||||
}
|
||||
|
||||
fun ObjectType.Layout.icon(
|
||||
image: String?,
|
||||
emoji: String?,
|
||||
iconName: String?,
|
||||
iconOption: Int?,
|
||||
name: String,
|
||||
builder: UrlBuilder
|
||||
): ObjectIcon? {
|
||||
return when (this) {
|
||||
ObjectType.Layout.OBJECT_TYPE -> handleObjectTypeIcon(
|
||||
emoji = emoji,
|
||||
iconName = iconName,
|
||||
iconOption = iconOption
|
||||
)
|
||||
return when (obj.layout) {
|
||||
ObjectType.Layout.OBJECT_TYPE -> {
|
||||
val asType = ObjectWrapper.Type(map = obj.map)
|
||||
asType.objectIcon()
|
||||
}
|
||||
|
||||
ObjectType.Layout.BASIC,
|
||||
ObjectType.Layout.IMAGE,
|
||||
ObjectType.Layout.SET,
|
||||
ObjectType.Layout.COLLECTION,
|
||||
ObjectType.Layout.IMAGE -> basicIcon(
|
||||
image = image,
|
||||
emoji = emoji,
|
||||
builder = builder,
|
||||
layout = this
|
||||
)
|
||||
ObjectType.Layout.COLLECTION -> {
|
||||
val fallback = objType?.objectFallbackIcon() ?: ObjectIcon.TypeIcon.Fallback.DEFAULT
|
||||
when {
|
||||
!objImage.isNullOrBlank() -> Basic.Image(
|
||||
hash = builder.thumbnail(objImage),
|
||||
fallback = fallback
|
||||
)
|
||||
|
||||
ObjectType.Layout.PROFILE,
|
||||
ObjectType.Layout.PARTICIPANT -> profileIcon(
|
||||
image = image,
|
||||
name = name,
|
||||
builder = builder
|
||||
)
|
||||
!objEmoji.isNullOrBlank() -> Basic.Emoji(
|
||||
unicode = objEmoji,
|
||||
fallback = fallback
|
||||
)
|
||||
|
||||
ObjectType.Layout.BOOKMARK -> bookmarkIcon(
|
||||
iconImage = image,
|
||||
builder = builder
|
||||
)
|
||||
else -> fallback
|
||||
}
|
||||
}
|
||||
|
||||
ObjectType.Layout.DATE -> emptyType()
|
||||
ObjectType.Layout.PARTICIPANT,
|
||||
ObjectType.Layout.PROFILE -> {
|
||||
when {
|
||||
!objImage.isNullOrBlank() -> ObjectIcon.Profile.Image(
|
||||
hash = builder.thumbnail(objImage),
|
||||
name = objName
|
||||
)
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
else -> ObjectIcon.Profile.Avatar(name = objName)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles icons for OBJECT_TYPE layout.
|
||||
*/
|
||||
private fun handleObjectTypeIcon(
|
||||
emoji: String?,
|
||||
iconName: String?,
|
||||
iconOption: Int?,
|
||||
): ObjectIcon? {
|
||||
return when {
|
||||
!emoji.isNullOrEmpty() -> {
|
||||
Basic.Emoji(
|
||||
unicode = emoji,
|
||||
emptyState = ObjectType.Layout.OBJECT_TYPE.emptyType()
|
||||
ObjectType.Layout.TODO -> {
|
||||
ObjectIcon.Task(isChecked = obj.done == true)
|
||||
}
|
||||
|
||||
ObjectType.Layout.FILE,
|
||||
ObjectType.Layout.VIDEO,
|
||||
ObjectType.Layout.AUDIO,
|
||||
ObjectType.Layout.PDF -> {
|
||||
ObjectIcon.File(
|
||||
mime = obj.fileMimeType,
|
||||
fileName = objName,
|
||||
extensions = obj.fileExt
|
||||
)
|
||||
}
|
||||
iconName.isNullOrEmpty() -> ObjectIcon.Empty.ObjectType
|
||||
else -> ObjectIcon.ObjectType(
|
||||
icon = CustomIcon(
|
||||
rawValue = iconName,
|
||||
color = CustomIconColor.fromIconOption(iconOption)
|
||||
),
|
||||
|
||||
ObjectType.Layout.BOOKMARK -> {
|
||||
val fallback = objType?.objectFallbackIcon()
|
||||
?: ObjectIcon.TypeIcon.Fallback.DEFAULT
|
||||
when {
|
||||
!objImage.isNullOrBlank() -> ObjectIcon.Bookmark(
|
||||
image = builder.thumbnail(objImage),
|
||||
fallback = fallback
|
||||
)
|
||||
|
||||
else -> fallback
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
objType?.objectFallbackIcon() ?: ObjectIcon.TypeIcon.Fallback.DEFAULT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun ObjectWrapper.Type.objectIcon(): ObjectIcon.TypeIcon {
|
||||
|
||||
if (isDeleted == true) {
|
||||
return ObjectIcon.TypeIcon.Deleted
|
||||
}
|
||||
|
||||
val objEmoji = iconEmoji
|
||||
val objIconName = iconName
|
||||
val objIconOption = iconOption
|
||||
return when {
|
||||
|
||||
!objEmoji.isNullOrEmpty() -> {
|
||||
ObjectIcon.TypeIcon.Emoji(
|
||||
unicode = objEmoji,
|
||||
rawValue = objIconName.orEmpty(),
|
||||
color = CustomIconColor.fromIconOption(objIconOption?.toInt())
|
||||
)
|
||||
}
|
||||
|
||||
!objIconName.isNullOrEmpty() -> ObjectIcon.TypeIcon.Default(
|
||||
rawValue = objIconName,
|
||||
color = CustomIconColor.fromIconOption(objIconOption?.toInt())
|
||||
)
|
||||
|
||||
else -> ObjectIcon.TypeIcon.Default(
|
||||
rawValue = ObjectIcon.TypeIcon.Default.DEFAULT_CUSTOM_ICON,
|
||||
color = CustomIconColor.DEFAULT
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun basicIcon(
|
||||
image: String?,
|
||||
emoji: String?,
|
||||
builder: UrlBuilder,
|
||||
layout: ObjectType.Layout
|
||||
): ObjectIcon? {
|
||||
private fun ObjectWrapper.Type.objectFallbackIcon(): ObjectIcon.TypeIcon.Fallback {
|
||||
|
||||
val objIconName = iconName
|
||||
return when {
|
||||
!image.isNullOrBlank() -> Basic.Image(
|
||||
hash = builder.thumbnail(image),
|
||||
emptyState = layout.emptyType()
|
||||
|
||||
!objIconName.isNullOrEmpty() -> ObjectIcon.TypeIcon.Fallback(
|
||||
rawValue = objIconName
|
||||
)
|
||||
|
||||
!emoji.isNullOrBlank() -> Basic.Emoji(
|
||||
unicode = emoji,
|
||||
emptyState = layout.emptyType()
|
||||
)
|
||||
|
||||
else -> null
|
||||
else -> {
|
||||
ObjectIcon.TypeIcon.Fallback.DEFAULT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun profileIcon(image: String?, name: String, builder: UrlBuilder): ObjectIcon? {
|
||||
return when {
|
||||
!image.isNullOrBlank() -> ObjectIcon.Profile.Image(hash = builder.thumbnail(image))
|
||||
else -> ObjectIcon.Profile.Avatar(name = name)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bookmarkIcon(iconImage: String?, builder: UrlBuilder): ObjectIcon? {
|
||||
return when {
|
||||
!iconImage.isNullOrBlank() -> ObjectIcon.Bookmark(image = builder.thumbnail(iconImage))
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun fileIcon(
|
||||
mime: String?,
|
||||
name: String?,
|
||||
extensions: String?
|
||||
): ObjectIcon {
|
||||
return ObjectIcon.File(
|
||||
mime = mime,
|
||||
fileName = name,
|
||||
extensions = extensions
|
||||
)
|
||||
}
|
||||
|
||||
private fun taskIcon(isChecked: Boolean): ObjectIcon {
|
||||
return ObjectIcon.Task(isChecked = isChecked)
|
||||
@Deprecated("Use ObjectWrapper.Basic.icon(builder, objType) instead")
|
||||
fun ObjectWrapper.Basic.objectIcon(builder: UrlBuilder): ObjectIcon {
|
||||
return ObjectIcon.None
|
||||
}
|
||||
|
|
|
@ -4,35 +4,35 @@ import com.anytypeio.anytype.core_models.Hash
|
|||
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.objects.custom_icon.CustomIcon
|
||||
import com.anytypeio.anytype.presentation.objects.custom_icon.CustomIconColor
|
||||
|
||||
sealed class ObjectIcon {
|
||||
|
||||
data object None :ObjectIcon()
|
||||
|
||||
sealed class Empty : ObjectIcon() {
|
||||
data object Page : Empty()
|
||||
data object List : Empty()
|
||||
data object Bookmark : Empty()
|
||||
data object Chat : Empty()
|
||||
data object ObjectType : Empty()
|
||||
data object Date : Empty()
|
||||
}
|
||||
data object None : ObjectIcon()
|
||||
|
||||
sealed class Basic : ObjectIcon() {
|
||||
data class Image(val hash: Hash, val emptyState: Empty = Empty.Page) : Basic()
|
||||
data class Emoji(val unicode: String, val emptyState: Empty = Empty.Page) : Basic()
|
||||
data class Image(
|
||||
val hash: Hash,
|
||||
val fallback: TypeIcon.Fallback = TypeIcon.Fallback.DEFAULT
|
||||
) : Basic()
|
||||
|
||||
data class Emoji(
|
||||
val unicode: String,
|
||||
val fallback: TypeIcon.Fallback = TypeIcon.Fallback.DEFAULT
|
||||
) : Basic()
|
||||
}
|
||||
|
||||
sealed class Profile : ObjectIcon() {
|
||||
data class Avatar(val name: String) : Profile()
|
||||
data class Image(val hash: Hash) : Profile()
|
||||
data class Image(val hash: Hash, val name: String) : Profile()
|
||||
}
|
||||
|
||||
data class Task(val isChecked: Boolean) : ObjectIcon()
|
||||
|
||||
data class Bookmark(val image: Url) : ObjectIcon()
|
||||
data class Bookmark(
|
||||
val image: Url,
|
||||
val fallback: TypeIcon
|
||||
) : ObjectIcon()
|
||||
|
||||
data class File(
|
||||
val mime: String?,
|
||||
|
@ -43,7 +43,59 @@ sealed class ObjectIcon {
|
|||
data object Deleted : ObjectIcon()
|
||||
|
||||
data class Checkbox(val isChecked: Boolean) : ObjectIcon()
|
||||
data class ObjectType(val icon: CustomIcon) : ObjectIcon()
|
||||
|
||||
sealed class TypeIcon : ObjectIcon() {
|
||||
|
||||
data object Deleted : TypeIcon()
|
||||
|
||||
data class Emoji(
|
||||
val unicode: String,
|
||||
val rawValue: String,
|
||||
val color: CustomIconColor,
|
||||
) : TypeIcon()
|
||||
|
||||
data class Default(
|
||||
val rawValue: String,
|
||||
val color: CustomIconColor,
|
||||
) : TypeIcon() {
|
||||
|
||||
/**
|
||||
* Returns the drawable resource name for this icon.
|
||||
*
|
||||
* The drawable name is generated by converting [rawValue] from kebab-case
|
||||
* (e.g., "battery-dead") to snake_case ("battery_dead") and prefixing it with "ci_".
|
||||
*/
|
||||
val drawableResId: String
|
||||
get() = DEFAULT_ICON_PREFIX + rawValue.toSnakeCase()
|
||||
|
||||
/**
|
||||
* Extension function that converts a kebab-case string to snake_case.
|
||||
*
|
||||
* Simply replaces all occurrences of '-' with '_'.
|
||||
*
|
||||
* @receiver String to be converted.
|
||||
* @return The snake_case version of the string.
|
||||
*/
|
||||
private fun String.toSnakeCase(): String = replace("-", "_")
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_ICON_PREFIX = "ci_"
|
||||
const val DEFAULT_CUSTOM_ICON = "extension-puzzle"
|
||||
|
||||
val DEFAULT = Default(DEFAULT_CUSTOM_ICON, CustomIconColor.DEFAULT)
|
||||
val DATE = Default("calendar", CustomIconColor.DEFAULT)
|
||||
}
|
||||
}
|
||||
|
||||
//we use this icon when we can't find the emoji for object or image icon can't be loaded
|
||||
data class Fallback(val rawValue: String) : TypeIcon() {
|
||||
companion object {
|
||||
const val DEFAULT_FALLBACK_ICON = "extension-puzzle"
|
||||
|
||||
val DEFAULT = Fallback(DEFAULT_FALLBACK_ICON)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class SpaceMemberIconView {
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
package com.anytypeio.anytype.presentation.objects.custom_icon
|
||||
|
||||
/**
|
||||
* Data class representing a custom icon.
|
||||
* @property rawValue The raw string representing the icon.
|
||||
* @property color The color of the icon, if any.
|
||||
*/
|
||||
data class CustomIcon(
|
||||
val rawValue: String,
|
||||
val color: CustomIconColor = CustomIconColor.DEFAULT
|
||||
) {
|
||||
/**
|
||||
* Returns the drawable resource name for this icon.
|
||||
*
|
||||
* The drawable name is generated by converting [rawValue] from kebab-case
|
||||
* (e.g., "battery-dead") to snake_case ("battery_dead") and prefixing it with "ci_".
|
||||
*/
|
||||
val drawableResId: String
|
||||
get() = DEFAULT_ICON_PREFIX + rawValue.toSnakeCase()
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_ICON_PREFIX = "ci_"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension function that converts a kebab-case string to snake_case.
|
||||
*
|
||||
* Simply replaces all occurrences of '-' with '_'.
|
||||
*
|
||||
* @receiver String to be converted.
|
||||
* @return The snake_case version of the string.
|
||||
*/
|
||||
private fun String.toSnakeCase(): String = replace("-", "_")
|
|
@ -128,7 +128,7 @@ class SpaceSettingsViewModel(
|
|||
defaultObjectTypeSettingItem = UiSpaceSettingsItem.DefaultObjectType(
|
||||
id = defaultType?.id,
|
||||
name = defaultType?.name.orEmpty(),
|
||||
icon = ObjectIcon.Empty.ObjectType
|
||||
icon = ObjectIcon.TypeIcon.Fallback.DEFAULT
|
||||
)
|
||||
} else {
|
||||
defaultObjectTypeSettingItem = UiSpaceSettingsItem.DefaultObjectType(
|
||||
|
@ -537,7 +537,7 @@ class SpaceSettingsViewModel(
|
|||
UiSpaceSettingsItem.DefaultObjectType(
|
||||
id = type.id,
|
||||
name = type.name.orEmpty(),
|
||||
icon = ObjectIcon.Empty.ObjectType
|
||||
icon = ObjectIcon.TypeIcon.Fallback.DEFAULT
|
||||
)
|
||||
} else {
|
||||
item
|
||||
|
|
|
@ -134,7 +134,7 @@ class CollectionAddRelationTest : ObjectSetViewModelTestSetup() {
|
|||
name = objectCollection.obj1.name.orEmpty(),
|
||||
description = objectCollection.obj1.description,
|
||||
hideIcon = false,
|
||||
icon = ObjectIcon.Empty.Page,
|
||||
icon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
relations = listOf(
|
||||
DefaultObjectRelationValueView.Empty(
|
||||
objectId = objectCollection.obj1.id,
|
||||
|
@ -155,7 +155,7 @@ class CollectionAddRelationTest : ObjectSetViewModelTestSetup() {
|
|||
name = objectCollection.obj2.name.orEmpty(),
|
||||
description = objectCollection.obj2.description,
|
||||
hideIcon = false,
|
||||
icon = ObjectIcon.Empty.Page,
|
||||
icon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
relations = listOf(
|
||||
DefaultObjectRelationValueView.Empty(
|
||||
objectId = objectCollection.obj2.id,
|
||||
|
|
|
@ -152,7 +152,7 @@ class DataViewBlockTargetObjectSetTest : EditorPresentationTestSetup() {
|
|||
title = null,
|
||||
background = ThemeColor.DEFAULT,
|
||||
isSelected = false,
|
||||
icon = ObjectIcon.Empty.List,
|
||||
icon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
decorations = listOf(BlockView.Decoration(style = BlockView.Decoration.Style.Card)),
|
||||
isCollection = false
|
||||
)
|
||||
|
@ -215,7 +215,7 @@ class DataViewBlockTargetObjectSetTest : EditorPresentationTestSetup() {
|
|||
title = null,
|
||||
background = ThemeColor.DEFAULT,
|
||||
isSelected = false,
|
||||
icon = ObjectIcon.Empty.List,
|
||||
icon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
decorations = listOf(BlockView.Decoration(style = BlockView.Decoration.Style.Card)),
|
||||
isCollection = false
|
||||
)
|
||||
|
@ -278,7 +278,7 @@ class DataViewBlockTargetObjectSetTest : EditorPresentationTestSetup() {
|
|||
title = null,
|
||||
background = ThemeColor.DEFAULT,
|
||||
isSelected = false,
|
||||
icon = ObjectIcon.Empty.List,
|
||||
icon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
decorations = listOf(BlockView.Decoration(style = BlockView.Decoration.Style.Card)),
|
||||
isCollection = false
|
||||
)
|
||||
|
@ -340,7 +340,7 @@ class DataViewBlockTargetObjectSetTest : EditorPresentationTestSetup() {
|
|||
title = null,
|
||||
background = ThemeColor.DEFAULT,
|
||||
isSelected = false,
|
||||
icon = ObjectIcon.Empty.List,
|
||||
icon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
decorations = listOf(BlockView.Decoration(style = BlockView.Decoration.Style.Card)),
|
||||
isCollection = true
|
||||
)
|
||||
|
@ -482,7 +482,7 @@ class DataViewBlockTargetObjectSetTest : EditorPresentationTestSetup() {
|
|||
title = null,
|
||||
background = ThemeColor.DEFAULT,
|
||||
isSelected = false,
|
||||
icon = ObjectIcon.Empty.Page,
|
||||
icon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
decorations = listOf(BlockView.Decoration(style = BlockView.Decoration.Style.Card)),
|
||||
isCollection = false
|
||||
)
|
||||
|
|
|
@ -312,7 +312,7 @@ class EditorLockPageTest : EditorPresentationTestSetup() {
|
|||
),
|
||||
BlockView.LinkToObject.Default.Text(
|
||||
id = link.id,
|
||||
icon = ObjectIcon.Empty.Page,
|
||||
icon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
decorations = listOf(
|
||||
BlockView.Decoration(
|
||||
background = link.parseThemeBackgroundColor()
|
||||
|
|
|
@ -17,6 +17,7 @@ import com.anytypeio.anytype.presentation.editor.editor.slash.SlashWidgetState
|
|||
import com.anytypeio.anytype.presentation.number.NumberParser
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectTypeView
|
||||
import com.anytypeio.anytype.presentation.objects.custom_icon.CustomIconColor
|
||||
import com.anytypeio.anytype.presentation.relations.ObjectRelationView
|
||||
import com.anytypeio.anytype.presentation.util.DefaultCoroutineTestRule
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
|
@ -369,11 +370,11 @@ class EditorSlashWidgetClicksTest: EditorPresentationTestSetup() {
|
|||
id = type1.id,
|
||||
key = type1.uniqueKey,
|
||||
name = type1.name.orEmpty(),
|
||||
icon = ObjectIcon.None,
|
||||
// ObjectIcon.Basic.Emoji(
|
||||
// unicode = type1.iconEmoji.orEmpty(),
|
||||
// emptyState = ObjectIcon.Empty.ObjectType
|
||||
// ),
|
||||
icon = ObjectIcon.TypeIcon.Emoji(
|
||||
unicode = type1.iconEmoji.orEmpty(),
|
||||
rawValue = "",
|
||||
color = CustomIconColor.DEFAULT
|
||||
),
|
||||
description = type1.description,
|
||||
)
|
||||
),
|
||||
|
@ -383,11 +384,11 @@ class EditorSlashWidgetClicksTest: EditorPresentationTestSetup() {
|
|||
key = type2.uniqueKey,
|
||||
name = type2.name.orEmpty(),
|
||||
description = type2.description,
|
||||
icon = ObjectIcon.None,
|
||||
// ObjectIcon.Basic.Emoji(
|
||||
// unicode = type2.iconEmoji.orEmpty(),
|
||||
// emptyState = ObjectIcon.Empty.ObjectType
|
||||
// ),
|
||||
icon = ObjectIcon.TypeIcon.Emoji(
|
||||
unicode = type2.iconEmoji.orEmpty(),
|
||||
rawValue = "",
|
||||
color = CustomIconColor.DEFAULT
|
||||
),
|
||||
)
|
||||
),
|
||||
SlashItem.ObjectType(
|
||||
|
@ -396,11 +397,11 @@ class EditorSlashWidgetClicksTest: EditorPresentationTestSetup() {
|
|||
key = type3.uniqueKey,
|
||||
name = type3.name.orEmpty(),
|
||||
description = type3.description,
|
||||
icon = ObjectIcon.None,
|
||||
// ObjectIcon.Basic.Emoji(
|
||||
// unicode = type3.iconEmoji.orEmpty(),
|
||||
// emptyState = ObjectIcon.Empty.ObjectType
|
||||
// ),
|
||||
icon = ObjectIcon.TypeIcon.Emoji(
|
||||
unicode = type3.iconEmoji.orEmpty(),
|
||||
rawValue = "",
|
||||
color = CustomIconColor.DEFAULT
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -21,6 +21,7 @@ import com.anytypeio.anytype.presentation.editor.editor.slash.SlashRelationView
|
|||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashWidgetState
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectTypeView
|
||||
import com.anytypeio.anytype.presentation.objects.custom_icon.CustomIconColor
|
||||
import com.anytypeio.anytype.presentation.relations.ObjectRelationView
|
||||
import com.anytypeio.anytype.presentation.util.CoroutinesTestRule
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
|
@ -471,11 +472,11 @@ class EditorSlashWidgetFilterTest : EditorPresentationTestSetup() {
|
|||
key = type1.uniqueKey,
|
||||
name = type1.name.orEmpty(),
|
||||
description = type1.description,
|
||||
icon = ObjectIcon.None
|
||||
// ObjectIcon.Basic.Emoji(
|
||||
// unicode = type1.iconEmoji.orEmpty(),
|
||||
// emptyState = ObjectIcon.Empty.ObjectType
|
||||
// ),
|
||||
icon = ObjectIcon.TypeIcon.Emoji(
|
||||
unicode = type1.iconEmoji.orEmpty(),
|
||||
rawValue = "",
|
||||
color = CustomIconColor.DEFAULT
|
||||
),
|
||||
)
|
||||
),
|
||||
SlashItem.ObjectType(
|
||||
|
@ -484,11 +485,11 @@ class EditorSlashWidgetFilterTest : EditorPresentationTestSetup() {
|
|||
key = type2.uniqueKey,
|
||||
name = type2.name.orEmpty(),
|
||||
description = type2.description,
|
||||
icon = ObjectIcon.None
|
||||
// ObjectIcon.Basic.Emoji(
|
||||
// unicode = type2.iconEmoji.orEmpty(),
|
||||
// emptyState = ObjectIcon.Empty.ObjectType
|
||||
// ),
|
||||
icon = ObjectIcon.TypeIcon.Emoji(
|
||||
unicode = type2.iconEmoji.orEmpty(),
|
||||
rawValue = "",
|
||||
color = CustomIconColor.DEFAULT
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -1517,11 +1518,11 @@ class EditorSlashWidgetFilterTest : EditorPresentationTestSetup() {
|
|||
key = type1.uniqueKey.orEmpty(),
|
||||
name = type1.name.orEmpty(),
|
||||
description = type1.description,
|
||||
icon = ObjectIcon.None
|
||||
// ObjectIcon.Basic.Emoji(
|
||||
// unicode = type1.iconEmoji.orEmpty(),
|
||||
// emptyState = ObjectIcon.Empty.ObjectType
|
||||
// ),
|
||||
icon = ObjectIcon.TypeIcon.Emoji(
|
||||
unicode = type1.iconEmoji.orEmpty(),
|
||||
rawValue = "",
|
||||
color = CustomIconColor.DEFAULT
|
||||
),
|
||||
)
|
||||
),
|
||||
SlashItem.ObjectType(
|
||||
|
@ -1530,11 +1531,11 @@ class EditorSlashWidgetFilterTest : EditorPresentationTestSetup() {
|
|||
key = type2.uniqueKey.orEmpty(),
|
||||
name = type2.name.orEmpty(),
|
||||
description = type2.description,
|
||||
icon = ObjectIcon.None
|
||||
// ObjectIcon.Basic.Emoji(
|
||||
// unicode = type2.iconEmoji.orEmpty(),
|
||||
// emptyState = ObjectIcon.Empty.ObjectType
|
||||
// ),
|
||||
icon = ObjectIcon.TypeIcon.Emoji(
|
||||
unicode = type2.iconEmoji.orEmpty(),
|
||||
rawValue = "",
|
||||
color = CustomIconColor.DEFAULT
|
||||
),
|
||||
)
|
||||
),
|
||||
SlashItem.ObjectType(
|
||||
|
@ -1543,11 +1544,11 @@ class EditorSlashWidgetFilterTest : EditorPresentationTestSetup() {
|
|||
key = type3.uniqueKey.orEmpty(),
|
||||
name = type3.name.orEmpty(),
|
||||
description = type3.description,
|
||||
icon = ObjectIcon.None
|
||||
// ObjectIcon.Basic.Emoji(
|
||||
// unicode = type3.iconEmoji.orEmpty(),
|
||||
// emptyState = ObjectIcon.Empty.ObjectType
|
||||
// ),
|
||||
icon = ObjectIcon.TypeIcon.Emoji(
|
||||
unicode = type3.iconEmoji.orEmpty(),
|
||||
rawValue = "",
|
||||
color = CustomIconColor.DEFAULT
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -653,7 +653,7 @@ class HomeScreenViewModelTest {
|
|||
id = firstLink.id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
obj = firstLink,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
indent = 0,
|
||||
path = widgetBlock.id + "/" + sourceObject.id + "/" + firstLink.id,
|
||||
name = WidgetView.Name.Default(
|
||||
|
@ -664,7 +664,7 @@ class HomeScreenViewModelTest {
|
|||
id = secondLink.id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
obj = secondLink,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
indent = 0,
|
||||
path = widgetBlock.id + "/" + sourceObject.id + "/" + secondLink.id,
|
||||
name = WidgetView.Name.Default(
|
||||
|
@ -1127,7 +1127,7 @@ class HomeScreenViewModelTest {
|
|||
id = firstLink.id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
obj = firstLink,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
indent = 0,
|
||||
path = favoriteWidgetBlock.id + "/" + favoriteSource.id + "/" + firstLink.id,
|
||||
name = WidgetView.Name.Default(
|
||||
|
@ -1138,7 +1138,7 @@ class HomeScreenViewModelTest {
|
|||
id = secondLink.id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
obj = secondLink,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
indent = 0,
|
||||
path = favoriteWidgetBlock.id + "/" + favoriteSource.id + "/" + secondLink.id,
|
||||
name = WidgetView.Name.Default(
|
||||
|
@ -1161,7 +1161,7 @@ class HomeScreenViewModelTest {
|
|||
id = firstLink.id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
obj = firstLink,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
indent = 0,
|
||||
path = recentWidgetBlock.id + "/" + recentSource.id + "/" + firstLink.id,
|
||||
name = WidgetView.Name.Default(
|
||||
|
@ -1172,7 +1172,7 @@ class HomeScreenViewModelTest {
|
|||
id = secondLink.id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
obj = secondLink,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
indent = 0,
|
||||
path = recentWidgetBlock.id + "/" + recentSource.id + "/" + secondLink.id,
|
||||
name = WidgetView.Name.Default(
|
||||
|
@ -1195,7 +1195,7 @@ class HomeScreenViewModelTest {
|
|||
id = firstLink.id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
obj = firstLink,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
indent = 0,
|
||||
path = setsWidgetBlock.id + "/" + setsSource.id + "/" + firstLink.id,
|
||||
name = WidgetView.Name.Default(
|
||||
|
@ -1206,7 +1206,7 @@ class HomeScreenViewModelTest {
|
|||
id = secondLink.id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
obj = secondLink,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
indent = 0,
|
||||
path = setsWidgetBlock.id + "/" + setsSource.id + "/" + secondLink.id,
|
||||
name = WidgetView.Name.Default(
|
||||
|
|
|
@ -337,7 +337,7 @@ class TreeWidgetContainerTest {
|
|||
obj = sourceLinks[0],
|
||||
path = widget.id + "/" + widget.source.id + "/" + sourceLinks[0].id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Branch(isExpanded = false),
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
name = WidgetView.Name.Default(
|
||||
prettyPrintName = fieldParser.getObjectName(sourceLinks[0])
|
||||
)
|
||||
|
@ -348,7 +348,7 @@ class TreeWidgetContainerTest {
|
|||
obj = sourceLinks[1],
|
||||
path = widget.id + "/" + widget.source.id + "/" + sourceLinks[1].id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
name = WidgetView.Name.Default(
|
||||
prettyPrintName = fieldParser.getObjectName(sourceLinks[1])
|
||||
)
|
||||
|
@ -359,7 +359,7 @@ class TreeWidgetContainerTest {
|
|||
obj = sourceLinks[2],
|
||||
path = widget.id + "/" + widget.source.id + "/" + sourceLinks[2].id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
name = WidgetView.Name.Default(
|
||||
prettyPrintName = fieldParser.getObjectName(sourceLinks[2])
|
||||
)
|
||||
|
@ -386,7 +386,7 @@ class TreeWidgetContainerTest {
|
|||
obj = sourceLinks[0],
|
||||
path = widget.id + "/" + widget.source.id + "/" + sourceLinks[0].id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Branch(isExpanded = true),
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
name = WidgetView.Name.Default(
|
||||
prettyPrintName = fieldParser.getObjectName(sourceLinks[0])
|
||||
)
|
||||
|
@ -397,7 +397,7 @@ class TreeWidgetContainerTest {
|
|||
obj = linkA1,
|
||||
path = widget.id + "/" + widget.source.id + "/" + sourceLinks[0].id + "/" + linkA1.id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
name = WidgetView.Name.Default(
|
||||
prettyPrintName = fieldParser.getObjectName(linkA1)
|
||||
)
|
||||
|
@ -408,7 +408,7 @@ class TreeWidgetContainerTest {
|
|||
obj = linkA2,
|
||||
path = widget.id + "/" + widget.source.id + "/" + sourceLinks[0].id + "/" + linkA2.id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
name = WidgetView.Name.Default(
|
||||
prettyPrintName = fieldParser.getObjectName(linkA2)
|
||||
)
|
||||
|
@ -419,7 +419,7 @@ class TreeWidgetContainerTest {
|
|||
obj = linkA3,
|
||||
path = widget.id + "/" + widget.source.id + "/" + sourceLinks[0].id + "/" + linkA3.id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
name = WidgetView.Name.Default(
|
||||
prettyPrintName = fieldParser.getObjectName(linkA3)
|
||||
)
|
||||
|
@ -430,7 +430,7 @@ class TreeWidgetContainerTest {
|
|||
obj = sourceLinks[1],
|
||||
path = widget.id + "/" + widget.source.id + "/" + sourceLinks[1].id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
name = WidgetView.Name.Default(
|
||||
prettyPrintName = fieldParser.getObjectName(sourceLinks[1])
|
||||
)
|
||||
|
@ -441,7 +441,7 @@ class TreeWidgetContainerTest {
|
|||
obj = sourceLinks[2],
|
||||
path = widget.id + "/" + widget.source.id + "/" + sourceLinks[2].id,
|
||||
elementIcon = WidgetView.Tree.ElementIcon.Leaf,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
name = WidgetView.Name.Default(
|
||||
prettyPrintName = fieldParser.getObjectName(sourceLinks[2])
|
||||
)
|
||||
|
|
|
@ -169,7 +169,7 @@ class TagAndStatusTests {
|
|||
name = "Untitled",
|
||||
type = "Type111",
|
||||
showIcon = false,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
cells = listOf(
|
||||
CellView.Description(
|
||||
id = recordId,
|
||||
|
@ -307,7 +307,7 @@ class TagAndStatusTests {
|
|||
name = "Untitled",
|
||||
type = "Type111",
|
||||
showIcon = false,
|
||||
objectIcon = ObjectIcon.Empty.Page,
|
||||
objectIcon = ObjectIcon.TypeIcon.Fallback.DEFAULT,
|
||||
cells = listOf(
|
||||
CellView.Description(
|
||||
id = recordId,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue