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

DROID-479 Editor | Redesign | Link-to-object appearance as card (#2643)

* DROID-479 card no icon, xml

* DROID-479 card, medium icon xml

* DROID-479 rename xml

* DROID-479 card, small icon, cover, xml

* DROID-479 medium icon, cover, xml

* DROID-479 new holders

* DROID-479 icon background

* DROID-479 mapping to card styles

* DROID-479 medium icon + cover, xml

* DROID-479 update object icon widget

* DROID-479 cards design

* DROID-479 link to object, holders

* DROID-479 update layout name

* DROID-479 show medium icon only for non-task layouts

* DROID-479 fallback to small icon

* DROID-479 tests fix

* DROID-479 decorations, text or card

* DROID-479 tests

* DROID-479 fixes

* DROID-479 fix

* DROID-479 ci

* DROID-479 ci off

Co-authored-by: konstantiniiv <ki@anytype.io>
This commit is contained in:
Konstantin Ivanov 2022-10-13 13:00:02 +02:00 committed by GitHub
parent 662eeabdfa
commit 394b68e716
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 1332 additions and 238 deletions

View file

@ -38,7 +38,10 @@ import com.anytypeio.anytype.core_ui.databinding.ItemBlockMediaPlaceholderBindin
import com.anytypeio.anytype.core_ui.databinding.ItemBlockNumberedBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockObjectLinkArchiveBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockObjectLinkBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockObjectLinkCardBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockObjectLinkCardMediumIconBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockObjectLinkCardMediumIconCoverBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockObjectLinkCardSmallIconBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockObjectLinkCardSmallIconCoverBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockObjectLinkDeleteBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockObjectLinkLoadingBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockPictureBinding
@ -82,7 +85,10 @@ import com.anytypeio.anytype.core_ui.features.editor.holders.other.DividerLine
import com.anytypeio.anytype.core_ui.features.editor.holders.other.Latex
import com.anytypeio.anytype.core_ui.features.editor.holders.other.LinkToObject
import com.anytypeio.anytype.core_ui.features.editor.holders.other.LinkToObjectArchive
import com.anytypeio.anytype.core_ui.features.editor.holders.other.LinkToObjectCard
import com.anytypeio.anytype.core_ui.features.editor.holders.other.LinkToObjectCardMediumIcon
import com.anytypeio.anytype.core_ui.features.editor.holders.other.LinkToObjectCardMediumIconCover
import com.anytypeio.anytype.core_ui.features.editor.holders.other.LinkToObjectCardSmallIcon
import com.anytypeio.anytype.core_ui.features.editor.holders.other.LinkToObjectCardSmallIconCover
import com.anytypeio.anytype.core_ui.features.editor.holders.other.LinkToObjectDelete
import com.anytypeio.anytype.core_ui.features.editor.holders.other.LinkToObjectLoading
import com.anytypeio.anytype.core_ui.features.editor.holders.other.TableOfContents
@ -145,7 +151,10 @@ import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_LATEX
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_NUMBERED
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_ARCHIVE
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_CARD
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_CARD_MEDIUM_ICON
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_CARD_MEDIUM_ICON_COVER
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_CARD_SMALL_ICON
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_CARD_SMALL_ICON_COVER
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_DEFAULT
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_DELETED
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_LOADING
@ -552,9 +561,36 @@ class BlockAdapter(
ItemBlockObjectLinkBinding.inflate(inflater, parent, false)
)
}
HOLDER_OBJECT_LINK_CARD -> {
LinkToObjectCard(
binding = ItemBlockObjectLinkCardBinding.inflate(
HOLDER_OBJECT_LINK_CARD_SMALL_ICON -> {
LinkToObjectCardSmallIcon(
binding = ItemBlockObjectLinkCardSmallIconBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
HOLDER_OBJECT_LINK_CARD_MEDIUM_ICON -> {
LinkToObjectCardMediumIcon(
binding = ItemBlockObjectLinkCardMediumIconBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
HOLDER_OBJECT_LINK_CARD_SMALL_ICON_COVER -> {
LinkToObjectCardSmallIconCover(
binding = ItemBlockObjectLinkCardSmallIconCoverBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
HOLDER_OBJECT_LINK_CARD_MEDIUM_ICON_COVER -> {
LinkToObjectCardMediumIconCover(
binding = ItemBlockObjectLinkCardMediumIconCoverBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
@ -1005,10 +1041,28 @@ class BlockAdapter(
item = blocks[position]
)
}
is LinkToObjectCard -> {
holder.processChangePayload(
is LinkToObjectCardSmallIcon -> {
holder.processChangePayloads(
payloads = payloads.typeOf(),
item = blocks[position]
item = blocks[position] as BlockView.LinkToObject.Default.Card.SmallIcon
)
}
is LinkToObjectCardMediumIcon -> {
holder.processChangePayloads(
payloads = payloads.typeOf(),
item = blocks[position] as BlockView.LinkToObject.Default.Card.MediumIcon
)
}
is LinkToObjectCardSmallIconCover -> {
holder.processChangePayloads(
payloads = payloads.typeOf(),
item = blocks[position] as BlockView.LinkToObject.Default.Card.SmallIconCover
)
}
is LinkToObjectCardMediumIconCover -> {
holder.processChangePayloads(
payloads = payloads.typeOf(),
item = blocks[position] as BlockView.LinkToObject.Default.Card.MediumIconCover
)
}
is LinkToObjectArchive -> {
@ -1130,7 +1184,7 @@ class BlockAdapter(
is HeaderOne -> holder.bind(blocks[position] as BlockView.Text.Header.One)
is HeaderTwo -> holder.bind(blocks[position] as BlockView.Text.Header.Two)
is HeaderThree -> holder.bind(blocks[position] as BlockView.Text.Header.Three)
is Checkbox -> holder.bind(blocks[position] as BlockView.Text.Checkbox )
is Checkbox -> holder.bind(blocks[position] as BlockView.Text.Checkbox)
is Bulleted -> holder.bind(blocks[position] as BlockView.Text.Bulleted)
is Numbered -> holder.bind(blocks[position] as BlockView.Text.Numbered)
is Toggle -> holder.bind(item = blocks[position] as BlockView.Text.Toggle)
@ -1258,9 +1312,27 @@ class BlockAdapter(
clicked = onClickListener
)
}
is LinkToObjectCard -> {
is LinkToObjectCardSmallIcon -> {
holder.bind(
item = blocks[position] as BlockView.LinkToObject.Default.Card,
item = blocks[position] as BlockView.LinkToObject.Default.Card.SmallIcon,
clicked = onClickListener
)
}
is LinkToObjectCardMediumIcon -> {
holder.bind(
item = blocks[position] as BlockView.LinkToObject.Default.Card.MediumIcon,
clicked = onClickListener
)
}
is LinkToObjectCardSmallIconCover -> {
holder.bind(
item = blocks[position] as BlockView.LinkToObject.Default.Card.SmallIconCover,
clicked = onClickListener
)
}
is LinkToObjectCardMediumIconCover -> {
holder.bind(
item = blocks[position] as BlockView.LinkToObject.Default.Card.MediumIconCover,
clicked = onClickListener
)
}

View file

@ -157,10 +157,17 @@ class BlockViewDiffUtil(
changes.add(OBJECT_TYPE_CHANGED)
}
if (newBlock is BlockView.LinkToObject.Default.Card && oldBlock is BlockView.LinkToObject.Default.Card) {
if (newBlock.coverImage != oldBlock.coverImage || newBlock.coverGradient != oldBlock.coverGradient ||
newBlock.coverColor != oldBlock.coverColor
)
if (newBlock is BlockView.LinkToObject.Default.Card.SmallIconCover
&& oldBlock is BlockView.LinkToObject.Default.Card.SmallIconCover) {
if (newBlock.cover != oldBlock.cover)
changes.add(OBJECT_COVER_CHANGED)
if (newBlock.background != oldBlock.background)
changes.add(BACKGROUND_COLOR_CHANGED)
}
if (newBlock is BlockView.LinkToObject.Default.Card.MediumIconCover
&& oldBlock is BlockView.LinkToObject.Default.Card.MediumIconCover) {
if (newBlock.cover != oldBlock.cover)
changes.add(OBJECT_COVER_CHANGED)
if (newBlock.background != oldBlock.background)
changes.add(BACKGROUND_COLOR_CHANGED)

View file

@ -2,8 +2,12 @@ package com.anytypeio.anytype.core_ui.features.editor.holders.other
import android.text.Spannable
import android.text.SpannableString
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.RecyclerView
@ -11,7 +15,6 @@ import com.anytypeio.anytype.core_ui.BuildConfig
import com.anytypeio.anytype.core_ui.R
import com.anytypeio.anytype.core_ui.common.SearchHighlightSpan
import com.anytypeio.anytype.core_ui.common.SearchTargetHighlightSpan
import com.anytypeio.anytype.core_ui.databinding.ItemBlockObjectLinkCardBinding
import com.anytypeio.anytype.core_ui.extensions.setBlockBackgroundColor
import com.anytypeio.anytype.core_ui.features.editor.BlockViewDiffUtil
import com.anytypeio.anytype.core_ui.features.editor.BlockViewHolder
@ -19,57 +22,56 @@ import com.anytypeio.anytype.core_ui.features.editor.EditorTouchProcessor
import com.anytypeio.anytype.core_ui.features.editor.SupportCustomTouchProcessor
import com.anytypeio.anytype.core_ui.features.editor.SupportNesting
import com.anytypeio.anytype.core_ui.features.editor.decoration.DecoratableCardViewHolder
import com.anytypeio.anytype.core_ui.features.editor.decoration.applySelectorOffset
import com.anytypeio.anytype.core_utils.ext.dimen
import com.anytypeio.anytype.core_utils.ext.gone
import com.anytypeio.anytype.core_utils.ext.removeSpans
import com.anytypeio.anytype.core_utils.ext.visible
import com.anytypeio.anytype.presentation.editor.cover.CoverColor
import com.anytypeio.anytype.presentation.editor.cover.CoverGradient
import com.anytypeio.anytype.core_models.ThemeColor
import com.anytypeio.anytype.core_ui.databinding.ItemBlockObjectLinkCardMediumIconBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockObjectLinkCardMediumIconCoverBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockObjectLinkCardSmallIconBinding
import com.anytypeio.anytype.core_ui.databinding.ItemBlockObjectLinkCardSmallIconCoverBinding
import com.anytypeio.anytype.core_ui.features.editor.decoration.EditorDecorationContainer
import com.anytypeio.anytype.core_ui.features.editor.decoration.applySelectorOffset
import com.anytypeio.anytype.core_ui.widgets.ObjectIconWidget
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
import com.anytypeio.anytype.presentation.objects.ObjectIcon
import com.bumptech.glide.Glide
class LinkToObjectCard(
private val binding: ItemBlockObjectLinkCardBinding
) : BlockViewHolder(binding.root),
abstract class LinkToObjectCard(
view: View
) : BlockViewHolder(view),
BlockViewHolder.IndentableHolder,
BlockViewHolder.DragAndDropHolder,
DecoratableCardViewHolder,
SupportCustomTouchProcessor,
SupportNesting {
private val root = binding.root
private val container = binding.containerWithBackground
private val cover = binding.cover
private val untitled = itemView.resources.getString(R.string.untitled)
private val objectIcon = binding.cardIcon
private val title = binding.cardName
private val description = binding.cardDescription
private val selected = binding.selected
private val type = binding.cardType
protected abstract val rootView: View
abstract val containerView: ConstraintLayout
override val decoratableContainer = binding.decorationContainer
override val decoratableCard = binding.card
private val untitled = itemView.resources.getString(R.string.untitled)
abstract val objectIconView: ObjectIconWidget
abstract val titleView: TextView
abstract val descriptionView: TextView
abstract val selectedView: View
abstract val objectTypeView: TextView
abstract override val decoratableContainer: EditorDecorationContainer
abstract override val decoratableCard: CardView
override val editorTouchProcessor = EditorTouchProcessor(
fallback = { e -> itemView.onTouchEvent(e) }
)
init {
itemView.setOnTouchListener { v, e -> editorTouchProcessor.process(v, e) }
applyDefaultOffsets()
}
fun bind(
protected fun bind(
item: BlockView.LinkToObject.Default.Card,
clicked: (ListenerType) -> Unit
) {
indentize(item)
selected.isSelected = item.isSelected
selected(item)
applyRootMargins(item)
@ -77,8 +79,6 @@ class LinkToObjectCard(
applyDescription(item)
applyCover(item)
applyBackground(item.background)
applySearchHighlight(item)
@ -90,56 +90,52 @@ class LinkToObjectCard(
itemView.setOnClickListener { clicked(ListenerType.LinkToObject(item.id)) }
}
private fun selected(item: BlockView.LinkToObject.Default.Card) {
selectedView.isSelected = item.isSelected
}
private fun applyName(item: BlockView.LinkToObject.Default.Card) {
val name = item.text
when {
name == null -> title.gone()
name == null -> titleView.gone()
name.isBlank() -> {
title.visible()
titleView.visible()
val sb = SpannableString(untitled)
title.setText(sb, TextView.BufferType.SPANNABLE)
titleView.setText(sb, TextView.BufferType.SPANNABLE)
}
else -> {
title.visible()
titleView.visible()
val sb = SpannableString(name)
title.setText(sb, TextView.BufferType.SPANNABLE)
titleView.setText(sb, TextView.BufferType.SPANNABLE)
}
}
}
private fun applyDescription(item: BlockView.LinkToObject.Default.Card) {
if (item.description.isNullOrBlank()) {
description.gone()
descriptionView.gone()
} else {
description.visible()
description.text = item.description
descriptionView.visible()
descriptionView.text = item.description
}
}
private fun applyImageOrEmoji(item: BlockView.LinkToObject.Default.Card) {
when (item.icon) {
ObjectIcon.None -> {
objectIcon.gone()
objectIconView.gone()
}
else -> {
objectIcon.visible()
objectIcon.setIcon(item.icon)
objectIconView.visible()
objectIconView.setIcon(item.icon)
}
}
}
private fun applyCover(item: BlockView.LinkToObject.Default.Card) {
setCover(
coverColor = item.coverColor,
coverGradient = item.coverGradient,
coverImage = item.coverImage
)
}
private fun applySearchHighlight(item: BlockView.Searchable) {
item.searchFields.find { it.key == BlockView.Searchable.Field.DEFAULT_SEARCH_FIELD_KEY }
?.let { field ->
applySearchHighlight(field, title)
applySearchHighlight(field, titleView)
} ?: clearSearchHighlights()
}
@ -156,7 +152,7 @@ class LinkToObjectCard(
)
}
if (field.isTargeted) {
content.setSpan(
content.setSpan(
SearchTargetHighlightSpan(),
field.target.first,
field.target.last,
@ -166,72 +162,73 @@ class LinkToObjectCard(
}
private fun clearSearchHighlights() {
title.editableText?.removeSpans<SearchHighlightSpan>()
title.editableText?.removeSpans<SearchTargetHighlightSpan>()
titleView.editableText?.removeSpans<SearchHighlightSpan>()
titleView.editableText?.removeSpans<SearchTargetHighlightSpan>()
}
override fun indentize(item: BlockView.Indentable) {
if (!BuildConfig.NESTED_DECORATION_ENABLED) {
root.updateLayoutParams<RecyclerView.LayoutParams> {
rootView.updateLayoutParams<RecyclerView.LayoutParams> {
marginStart = item.indent * dimen(R.dimen.indent)
}
}
}
fun processChangePayload(payloads: List<BlockViewDiffUtil.Payload>, item: BlockView) {
check(item is BlockView.LinkToObject.Default.Card) { "Expected a link to object block card, but was: $item" }
payloads.forEach { payload ->
if (payload.changes.contains(BlockViewDiffUtil.SELECTION_CHANGED)) {
selected.isSelected = item.isSelected
applyImageOrEmoji(item)
}
if (payload.isSearchHighlightChanged) {
applySearchHighlight(item)
}
if (payload.isObjectTitleChanged)
applyName(item)
if (payload.isObjectIconChanged)
applyImageOrEmoji(item)
if (payload.isObjectDescriptionChanged)
applyDescription(item)
if (payload.isObjectCoverChanged)
applyCover(item)
if (payload.isBackgroundColorChanged)
applyBackground(item.background)
if (payload.isObjectTypeChanged)
applyObjectType(item)
protected fun processChangeBasePayloads(
payload: BlockViewDiffUtil.Payload,
item: BlockView.LinkToObject.Default.Card
) {
if (payload.isSelectionChanged) {
selected(item)
}
if (payload.isSearchHighlightChanged) {
applySearchHighlight(item)
}
if (payload.isObjectTitleChanged) {
applyName(item)
}
if (payload.isObjectIconChanged) {
applyImageOrEmoji(item)
}
if (payload.isObjectDescriptionChanged) {
applyDescription(item)
}
if (payload.isBackgroundColorChanged) {
applyBackground(item.background)
}
if (payload.isObjectTypeChanged) {
applyObjectType(item)
}
}
private fun setCover(
coverColor: CoverColor?,
coverImage: String?,
coverGradient: String?
protected fun applyCover(
coverView: ImageView,
cover: BlockView.LinkToObject.Default.Card.Cover?
) {
when {
coverColor != null -> {
cover.apply {
when (cover) {
is BlockView.LinkToObject.Default.Card.Cover.Color -> {
coverView.apply {
visible()
setImageDrawable(null)
setBackgroundColor(coverColor.color)
setBackgroundColor(cover.color.color)
}
}
coverImage != null -> {
cover.apply {
is BlockView.LinkToObject.Default.Card.Cover.Image -> {
coverView.apply {
visible()
setBackgroundColor(0)
Glide
.with(itemView)
.load(coverImage)
.load(cover.url)
.centerCrop()
.into(this)
}
}
coverGradient != null -> {
cover.apply {
is BlockView.LinkToObject.Default.Card.Cover.Gradient -> {
coverView.apply {
setImageDrawable(null)
setBackgroundColor(0)
when (coverGradient) {
when (cover.gradient) {
CoverGradient.YELLOW -> setBackgroundResource(R.drawable.cover_gradient_yellow)
CoverGradient.RED -> setBackgroundResource(R.drawable.cover_gradient_red)
CoverGradient.BLUE -> setBackgroundResource(R.drawable.cover_gradient_blue)
@ -245,30 +242,29 @@ class LinkToObjectCard(
}
}
else -> {
cover.apply {
coverView.apply {
setImageDrawable(null)
setBackgroundColor(0)
gone()
}
}
}
}
private fun applyBackground(background: ThemeColor) {
container.setBlockBackgroundColor(background)
containerView.setBlockBackgroundColor(background)
}
private fun applyRootMargins(item: BlockView.LinkToObject.Default.Card) {
if (!BuildConfig.NESTED_DECORATION_ENABLED) {
if (item.isPreviousBlockMedia) {
root.updateLayoutParams<RecyclerView.LayoutParams> {
rootView.updateLayoutParams<RecyclerView.LayoutParams> {
apply { topMargin = 0 }
}
} else {
root.updateLayoutParams<RecyclerView.LayoutParams> {
rootView.updateLayoutParams<RecyclerView.LayoutParams> {
apply {
topMargin =
root.resources.getDimension(R.dimen.default_link_card_root_margin_top)
rootView.resources.getDimension(R.dimen.default_link_card_root_margin_top)
.toInt()
}
}
@ -278,23 +274,23 @@ class LinkToObjectCard(
private fun applyObjectType(item: BlockView.LinkToObject.Default.Card) {
if (!item.objectTypeName.isNullOrBlank()) {
type.text = item.objectTypeName
type.visible()
objectTypeView.text = item.objectTypeName
objectTypeView.visible()
} else {
type.gone()
objectTypeView.gone()
}
}
private fun applyDefaultOffsets() {
protected fun applyDefaultOffsets() {
if (!BuildConfig.NESTED_DECORATION_ENABLED) {
root.updatePadding(
rootView.updatePadding(
left = dimen(R.dimen.default_document_item_padding_start),
right = dimen(R.dimen.default_document_item_padding_end)
)
root.updateLayoutParams<RecyclerView.LayoutParams> {
rootView.updateLayoutParams<RecyclerView.LayoutParams> {
bottomMargin = dimen(R.dimen.dp_10)
}
binding.card.updateLayoutParams<FrameLayout.LayoutParams> {
decoratableCard.updateLayoutParams<FrameLayout.LayoutParams> {
marginStart = dimen(R.dimen.dp_12)
marginEnd = dimen(R.dimen.dp_12)
}
@ -304,10 +300,160 @@ class LinkToObjectCard(
override fun applyDecorations(decorations: List<BlockView.Decoration>) {
super.applyDecorations(decorations)
if (BuildConfig.NESTED_DECORATION_ENABLED) {
binding.selected.applySelectorOffset<FrameLayout.LayoutParams>(
content = binding.card,
selectedView.applySelectorOffset<FrameLayout.LayoutParams>(
content = decoratableCard,
res = itemView.resources
)
}
}
}
class LinkToObjectCardSmallIcon(binding: ItemBlockObjectLinkCardSmallIconBinding) :
LinkToObjectCard(binding.root) {
override val rootView = binding.root
override val containerView = binding.containerWithBackground
override val objectIconView = binding.cardIcon
override val titleView = binding.cardName
override val descriptionView = binding.cardDescription
override val objectTypeView = binding.cardType
override val decoratableContainer = binding.decorationContainer
override val selectedView = binding.selected
override val decoratableCard = binding.card
init {
itemView.setOnTouchListener { v, e -> editorTouchProcessor.process(v, e) }
applyDefaultOffsets()
}
fun bind(
item: BlockView.LinkToObject.Default.Card.SmallIcon,
clicked: (ListenerType) -> Unit
) {
super.bind(item = item, clicked = clicked)
}
fun processChangePayloads(
payloads: List<BlockViewDiffUtil.Payload>,
item: BlockView.LinkToObject.Default.Card.SmallIcon
) {
payloads.forEach { payload ->
processChangeBasePayloads(payload, item)
}
}
}
class LinkToObjectCardMediumIcon(binding: ItemBlockObjectLinkCardMediumIconBinding) :
LinkToObjectCard(binding.root) {
override val rootView = binding.root
override val containerView = binding.containerWithBackground
override val objectIconView = binding.cardIcon
override val titleView = binding.cardName
override val descriptionView = binding.cardDescription
override val objectTypeView = binding.cardType
override val decoratableContainer = binding.decorationContainer
override val selectedView = binding.selected
override val decoratableCard = binding.card
init {
itemView.setOnTouchListener { v, e -> editorTouchProcessor.process(v, e) }
applyDefaultOffsets()
}
fun bind(
item: BlockView.LinkToObject.Default.Card.MediumIcon,
clicked: (ListenerType) -> Unit
) {
super.bind(item = item, clicked = clicked)
}
fun processChangePayloads(
payloads: List<BlockViewDiffUtil.Payload>,
item: BlockView.LinkToObject.Default.Card.MediumIcon
) {
payloads.forEach { payload ->
processChangeBasePayloads(payload, item)
}
}
}
class LinkToObjectCardSmallIconCover(binding: ItemBlockObjectLinkCardSmallIconCoverBinding) :
LinkToObjectCard(binding.root) {
override val rootView = binding.root
override val containerView = binding.containerWithBackground
override val objectIconView = binding.cardIcon
override val titleView = binding.cardName
override val descriptionView = binding.cardDescription
override val objectTypeView = binding.cardType
override val decoratableContainer = binding.decorationContainer
override val decoratableCard = binding.card
override val selectedView = binding.selected
private val coverView = binding.coverImage
init {
itemView.setOnTouchListener { v, e -> editorTouchProcessor.process(v, e) }
applyDefaultOffsets()
}
fun bind(
item: BlockView.LinkToObject.Default.Card.SmallIconCover,
clicked: (ListenerType) -> Unit
) {
super.bind(item = item, clicked = clicked)
applyCover(coverView = coverView, cover = item.cover)
}
fun processChangePayloads(
payloads: List<BlockViewDiffUtil.Payload>,
item: BlockView.LinkToObject.Default.Card.SmallIconCover
) {
payloads.forEach { payload ->
if (payload.isObjectCoverChanged) {
applyCover(coverView = coverView, cover = item.cover)
}
processChangeBasePayloads(payload, item)
}
}
}
class LinkToObjectCardMediumIconCover(binding: ItemBlockObjectLinkCardMediumIconCoverBinding) :
LinkToObjectCard(binding.root) {
override val rootView = binding.root
override val containerView = binding.containerWithBackground
override val objectIconView = binding.cardIcon
override val titleView = binding.cardName
override val descriptionView = binding.cardDescription
override val objectTypeView = binding.cardType
override val decoratableContainer = binding.decorationContainer
override val decoratableCard = binding.card
override val selectedView = binding.selected
private val coverView = binding.coverImage
init {
itemView.setOnTouchListener { v, e -> editorTouchProcessor.process(v, e) }
applyDefaultOffsets()
}
fun bind(
item: BlockView.LinkToObject.Default.Card.MediumIconCover,
clicked: (ListenerType) -> Unit
) {
super.bind(item = item, clicked = clicked)
applyCover(coverView = coverView, cover = item.cover)
}
fun processChangePayloads(
payloads: List<BlockViewDiffUtil.Payload>,
item: BlockView.LinkToObject.Default.Card.MediumIconCover
) {
payloads.forEach { payload ->
if (payload.isObjectCoverChanged) {
applyCover(coverView = coverView, cover = item.cover)
}
processChangeBasePayloads(payload, item)
}
}
}

View file

@ -28,7 +28,7 @@ class ObjectIconWidget @JvmOverloads constructor(
) : FrameLayout(context, attrs, defStyleAttr) {
companion object {
val DEFAULT_SIZE = 24
const val DEFAULT_SIZE = 24
}
val binding = WidgetObjectIconBinding.inflate(
@ -36,6 +36,7 @@ class ObjectIconWidget @JvmOverloads constructor(
)
private var imageCornerRadius: Float = 0F
private var isImageWithCorners: Boolean = false
init {
setupAttributeValues(attrs)
@ -63,6 +64,10 @@ class ObjectIconWidget @JvmOverloads constructor(
attrs.getBoolean(R.styleable.ObjectIconWidget_hasEmojiRounded8Background, false)
val hasInitialRounded8Background =
attrs.getBoolean(R.styleable.ObjectIconWidget_hasInitialRounded8Background, false)
val hasEmojiRounded10Background =
attrs.getBoolean(R.styleable.ObjectIconWidget_hasEmojiRounded10Background, false)
val hasInitialRoundedCornerBackground =
attrs.getBoolean(R.styleable.ObjectIconWidget_hasInitialRoundedCornerBackground, false)
ivEmoji.updateLayoutParams<LayoutParams> {
this.height = emojiSize
@ -91,7 +96,9 @@ class ObjectIconWidget @JvmOverloads constructor(
emojiContainer.setBackgroundResource(R.drawable.rectangle_object_icon_emoji_background_8)
}
if (!hasEmojiCircleBackground && !hasEmojiRounded12Background && !hasEmojiRounded8Background) {
if (!hasEmojiCircleBackground && !hasEmojiRounded12Background && !hasEmojiRounded8Background
&& !hasEmojiRounded10Background
) {
emojiContainer.background = null
}
@ -99,6 +106,14 @@ class ObjectIconWidget @JvmOverloads constructor(
initialContainer.setBackgroundResource(R.drawable.rectangle_avatar_initial_background_8)
}
if (hasEmojiRounded10Background) {
emojiContainer.setBackgroundResource(R.drawable.bg_rect_10_radius)
}
if (hasInitialRoundedCornerBackground) {
initialContainer.setBackgroundResource(R.drawable.bg_circle_with_corner)
}
val initialTextSize =
attrs.getDimensionPixelSize(R.styleable.ObjectIconWidget_initialTextSize, 0)
if (initialTextSize > 0) initial.setTextSize(
@ -109,6 +124,9 @@ class ObjectIconWidget @JvmOverloads constructor(
imageCornerRadius =
attrs.getDimensionPixelSize(R.styleable.ObjectIconWidget_imageCornerRadius, 2)
.toFloat()
isImageWithCorners =
attrs.getBoolean(R.styleable.ObjectIconWidget_isImageWithCorners, false)
attrs.recycle()
}
@ -153,7 +171,9 @@ class ObjectIconWidget @JvmOverloads constructor(
ivBookmark.setImageDrawable(null)
ivBookmark.gone()
initialContainer.visible()
initialContainer.setBackgroundResource(R.drawable.object_in_list_background_profile_initial)
if (initialContainer.background == null) {
initialContainer.setBackgroundResource(R.drawable.object_in_list_background_profile_initial)
}
initial.setTextColor(context.color(R.color.text_white))
initial.setHintTextColor(context.color(R.color.text_tertiary))
initial.text = name.firstOrNull()?.uppercaseChar()?.toString()
@ -169,7 +189,9 @@ class ObjectIconWidget @JvmOverloads constructor(
ivBookmark.setImageDrawable(null)
ivBookmark.gone()
initialContainer.visible()
initialContainer.setBackgroundResource(R.drawable.object_in_list_background_basic_initial)
if (initialContainer.background == null) {
initialContainer.setBackgroundResource(R.drawable.object_in_list_background_basic_initial)
}
initial.setTextColor(textColor)
initial.setHintTextColor(textColor)
initial.text = name.firstOrNull()?.uppercaseChar()?.toString()
@ -210,6 +232,11 @@ class ObjectIconWidget @JvmOverloads constructor(
ivBookmark.setImageDrawable(null)
ivBookmark.gone()
ivImage.setCircularShape()
if (isImageWithCorners) {
ivImage.setStrokeWidthResource(R.dimen.dp_2)
ivImage.strokeColor =
this.root.context.getColorStateList(R.color.background_primary)
}
}
Glide
.with(this)
@ -231,6 +258,11 @@ class ObjectIconWidget @JvmOverloads constructor(
ivBookmark.setImageDrawable(null)
ivImage.visible()
ivImage.setCorneredShape(imageCornerRadius)
if (isImageWithCorners) {
ivImage.setStrokeWidthResource(R.dimen.dp_2)
ivImage.strokeColor =
this.root.context.getColorStateList(R.color.background_primary)
}
}
Glide
.with(this)

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<stroke
android:width="@dimen/dp_2"
android:color="@color/background_secondary" />
<solid android:color="@color/shape_secondary" />
</shape>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/shape_tertiary" />
<corners android:radius="@dimen/dp_10" />
<stroke
android:width="@dimen/dp_2"
android:color="@color/background_secondary" />
</shape>

View file

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.anytypeio.anytype.core_ui.features.editor.holders.other.LinkToObjectCardMediumIcon">
<com.anytypeio.anytype.core_ui.features.editor.decoration.EditorDecorationContainer
android:id="@+id/decorationContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
style="@style/DefaultLinkCardBlockCardStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/containerWithBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="16dp">
<TextView
android:id="@+id/cardName"
style="@style/ObjectLinkBlockCardTitleStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:includeFontPadding="false"
app:layout_constraintBottom_toTopOf="@+id/cardDescription"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/cardIcon"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="What is Aesthetic intelligence?"
tools:visibility="visible" />
<TextView
android:id="@+id/cardDescription"
style="@style/ObjectLinkBlockCardDescriptionStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toTopOf="@+id/cardType"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/cardIcon"
app:layout_constraintTop_toBottomOf="@+id/cardName"
tools:text="One thing I love about science fiction is the way it can reflect what is on peoples minds. Growing up in the sixties, I read a ton of sci-fi, and most of the novels involved either robots or space travel and life on other planets..."
tools:visibility="visible" />
<TextView
android:id="@+id/cardType"
style="@style/ObjectLinkBlockCardObjectTypeStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/cardIcon"
app:layout_constraintTop_toBottomOf="@+id/cardDescription"
tools:ignore="TextContrastCheck"
tools:text="Page"
tools:visibility="visible" />
<com.anytypeio.anytype.core_ui.widgets.ObjectIconWidget
android:id="@+id/cardIcon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:checkboxSize="30dp"
app:emojiSize="30dp"
app:hasEmojiRounded10Background="true"
app:hasInitialRoundedCornerBackground="true"
app:imageCornerRadius="@dimen/dp_2"
app:imageSize="48dp"
app:initialTextSize="28sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<View
android:id="@+id/selected"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/item_block_multi_select_mode_selector"
tools:background="@drawable/item_block_multi_select_selected" />
</FrameLayout>

View file

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.anytypeio.anytype.core_ui.features.editor.holders.other.LinkToObjectCardMediumIconCover">
<com.anytypeio.anytype.core_ui.features.editor.decoration.EditorDecorationContainer
android:id="@+id/decorationContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
style="@style/DefaultLinkCardBlockCardStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/containerWithBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/coverImage"
android:layout_width="0dp"
android:layout_height="136dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_end="@dimen/dp_16" />
<TextView
android:id="@+id/cardName"
style="@style/ObjectLinkBlockCardTitleStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:includeFontPadding="false"
app:layout_constraintBottom_toTopOf="@+id/cardDescription"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/coverImage"
app:layout_constraintVertical_chainStyle="packed"
app:layout_goneMarginStart="@dimen/dp_16"
tools:text="What is Aesthetic intelligence?"
tools:visibility="visible" />
<TextView
android:id="@+id/cardDescription"
style="@style/ObjectLinkBlockCardDescriptionStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toTopOf="@+id/cardType"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardName"
tools:text="One thing I love about science fiction is the way it can reflect what is on peoples minds. Growing up in the sixties, I read a ton of sci-fi, and most of the novels involved either robots or space travel and life on other planets..."
tools:visibility="visible" />
<TextView
android:id="@+id/cardType"
style="@style/ObjectLinkBlockCardObjectTypeStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toTopOf="@id/guidelineHorizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardDescription"
tools:ignore="TextContrastCheck"
tools:text="Page"
tools:visibility="visible" />
<com.anytypeio.anytype.core_ui.widgets.ObjectIconWidget
android:id="@+id/cardIcon"
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_marginStart="14dp"
android:layout_marginTop="102dp"
app:emojiSize="30dp"
app:hasEmojiRounded10Background="true"
app:hasInitialRoundedCornerBackground="true"
app:imageCornerRadius="@dimen/dp_2"
app:imageSize="50dp"
app:initialTextSize="28sp"
app:isImageWithCorners="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<View
android:id="@+id/selected"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/item_block_multi_select_mode_selector"
tools:background="@drawable/item_block_multi_select_selected" />
</FrameLayout>

View file

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.anytypeio.anytype.core_ui.features.editor.holders.other.LinkToObjectCardSmallIcon">
<com.anytypeio.anytype.core_ui.features.editor.decoration.EditorDecorationContainer
android:id="@+id/decorationContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
style="@style/DefaultLinkCardBlockCardStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/containerWithBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_end="@dimen/dp_16" />
<TextView
android:id="@+id/cardName"
style="@style/ObjectLinkBlockCardTitleStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:includeFontPadding="false"
app:layout_goneMarginStart="@dimen/dp_16"
app:layout_constraintBottom_toTopOf="@+id/cardDescription"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/cardIcon"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="What is Aesthetic intelligence?"
tools:visibility="visible" />
<TextView
android:id="@+id/cardDescription"
style="@style/ObjectLinkBlockCardDescriptionStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toTopOf="@+id/cardType"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardName"
tools:text="One thing I love about science fiction is the way it can reflect what is on peoples minds. Growing up in the sixties, I read a ton of sci-fi, and most of the novels involved either robots or space travel and life on other planets..."
tools:visibility="visible" />
<TextView
android:id="@+id/cardType"
style="@style/ObjectLinkBlockCardObjectTypeStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toTopOf="@id/guidelineHorizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardDescription"
tools:ignore="TextContrastCheck"
tools:text="Page"
tools:visibility="visible" />
<com.anytypeio.anytype.core_ui.widgets.ObjectIconWidget
android:id="@+id/cardIcon"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:imageSize="18dp"
app:emojiSize="18dp"
app:checkboxSize="18dp"
app:initialTextSize="11sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<View
android:id="@+id/selected"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/item_block_multi_select_mode_selector"
tools:background="@drawable/item_block_multi_select_selected" />
</FrameLayout>

View file

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.anytypeio.anytype.core_ui.features.editor.holders.other.LinkToObjectCardSmallIconCover">
<com.anytypeio.anytype.core_ui.features.editor.decoration.EditorDecorationContainer
android:id="@+id/decorationContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
style="@style/DefaultLinkCardBlockCardStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/containerWithBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/coverImage"
android:layout_width="0dp"
android:layout_height="136dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_end="@dimen/dp_16" />
<TextView
android:id="@+id/cardName"
style="@style/ObjectLinkBlockCardTitleStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="16dp"
android:includeFontPadding="false"
app:layout_constraintBottom_toTopOf="@+id/cardDescription"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/cardIcon"
app:layout_constraintTop_toBottomOf="@id/coverImage"
app:layout_constraintVertical_chainStyle="packed"
app:layout_goneMarginStart="@dimen/dp_16"
tools:text="What is Aesthetic intelligence?"
tools:visibility="visible" />
<TextView
android:id="@+id/cardDescription"
style="@style/ObjectLinkBlockCardDescriptionStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toTopOf="@+id/cardType"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardName"
tools:text="One thing I love about science fiction is the way it can reflect what is on peoples minds. Growing up in the sixties, I read a ton of sci-fi, and most of the novels involved either robots or space travel and life on other planets..."
tools:visibility="visible" />
<TextView
android:id="@+id/cardType"
style="@style/ObjectLinkBlockCardObjectTypeStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toTopOf="@id/guidelineHorizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardDescription"
tools:ignore="TextContrastCheck"
tools:text="Page"
tools:visibility="visible" />
<com.anytypeio.anytype.core_ui.widgets.ObjectIconWidget
android:id="@+id/cardIcon"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginStart="16dp"
android:layout_marginTop="12dp"
app:checkboxSize="18dp"
app:emojiSize="18dp"
app:imageSize="18dp"
app:initialTextSize="11sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/coverImage"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<View
android:id="@+id/selected"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/item_block_multi_select_mode_selector"
tools:background="@drawable/item_block_multi_select_selected" />
</FrameLayout>

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="ObjectLinkBlockCardDescriptionStyle">
<item name="android:fontFamily">@font/inter_regular</item>
<item name="android:textColor">@color/text_primary</item>
<item name="android:textSize">12sp</item>
<item name="android:maxLines">2</item>
<item name="android:ellipsize">end</item>
<item name="android:lineHeight">18sp</item>
</style>
<style name="ObjectLinkBlockCardTitleStyle">
<item name="android:fontFamily">@font/inter_medium</item>
<item name="android:textColor">@color/text_primary</item>
<item name="android:textSize">15sp</item>
<item name="android:maxLines">1</item>
<item name="android:lineHeight">18sp</item>
<item name="android:ellipsize">end</item>
</style>
<style name="ObjectLinkBlockTextStyle">
<item name="android:background">@null</item>
<item name="android:fontFamily">@font/inter_medium</item>
<item name="android:textColor">@color/text_primary</item>
<item name="android:textSize">17sp</item>
<item name="android:lineHeight">22sp</item>
</style>
</resources>

View file

@ -7,12 +7,15 @@
<attr name="emojiSize" format="dimension" />
<attr name="imageSize" format="dimension" />
<attr name="checkboxSize" format="dimension" />
<attr name="hasEmojiRounded10Background" format="boolean" />
<attr name="hasEmojiCircleBackground" format="boolean" />
<attr name="hasEmojiRounded12Background" format="boolean" />
<attr name="hasEmojiRounded8Background" format="boolean" />
<attr name="hasInitialRounded8Background" format="boolean" />
<attr name="initialTextSize" format="dimension" />
<attr name="imageCornerRadius" format="dimension" />
<attr name="isImageWithCorners" format="boolean" />
<attr name="hasInitialRoundedCornerBackground" format="boolean" />
</declare-styleable>
<declare-styleable name="ObjectIconTextWidget">
<attr name="nameTextSize" format="dimension" />

View file

@ -856,6 +856,7 @@
<item name="hasEmojiRounded8Background">false</item>
<item name="hasEmojiRounded12Background">false</item>
<item name="hasInitialRounded8Background">false</item>
<item name="hasEmojiRounded10Background">false</item>
</style>
<style name="ShapeAppearance.MaterialComponents.Circle">
@ -931,13 +932,12 @@
</style>
<!-- card -->
<style name="DefaultLinkCardBlockCardStyle">
<item name="android:minHeight">96dp</item>
<item name="cardCornerRadius">16dp</item>
<style name="DefaultLinkCardBlockCardStyle" parent="CardView">
<item name="cardCornerRadius">12dp</item>
<item name="cardElevation">0dp</item>
<item name="rippleColor">@android:color/transparent</item>
<item name="strokeColor">@color/shape_primary</item>
<item name="strokeWidth">0.5dp</item>
<item name="strokeColor">@color/shape_tertiary</item>
<item name="strokeWidth">1dp</item>
</style>
<!-- Editor, Table of Contents block -->
@ -1053,7 +1053,6 @@
<item name="android:fontFamily">@font/inter_medium</item>
<item name="android:textColor">@color/text_primary</item>
<item name="android:textSize">17sp</item>
<item name="lineHeight">22sp</item>
</style>
<style name="ObjectLinkBlockRelationsStyle">
@ -1063,5 +1062,28 @@
<item name="android:textSize">12sp</item>
</style>
<!-- Editor, object link as card block-->
<style name="ObjectLinkBlockCardTitleStyle">
<item name="android:fontFamily">@font/inter_medium</item>
<item name="android:textColor">@color/text_primary</item>
<item name="android:textSize">15sp</item>
<item name="android:maxLines">1</item>
<item name="android:ellipsize">end</item>
</style>
<style name="ObjectLinkBlockCardDescriptionStyle">
<item name="android:fontFamily">@font/inter_regular</item>
<item name="android:textColor">@color/text_primary</item>
<item name="android:textSize">12sp</item>
<item name="android:maxLines">2</item>
<item name="android:ellipsize">end</item>
</style>
<style name="ObjectLinkBlockCardObjectTypeStyle">
<item name="android:fontFamily">@font/inter_regular</item>
<item name="android:textColor">@color/text_secondary</item>
<item name="android:textSize">12sp</item>
<item name="android:maxLines">1</item>
<item name="android:ellipsize">end</item>
</style>
</resources>

View file

@ -11,7 +11,7 @@ class SetLinkAppearance(
private val repository: BlockRepository,
) : BaseUseCase<Payload, SetLinkAppearance.Params>() {
class Params(
data class Params(
val contextId: String,
val blockId: String,
val content: Block.Content.Link

View file

@ -316,7 +316,16 @@ fun List<BlockView>.enterSAM(
is BlockView.LinkToObject.Default.Text -> view.copy(
isSelected = isSelected
)
is BlockView.LinkToObject.Default.Card -> view.copy(
is BlockView.LinkToObject.Default.Card.SmallIcon -> view.copy(
isSelected = isSelected
)
is BlockView.LinkToObject.Default.Card.MediumIcon -> view.copy(
isSelected = isSelected
)
is BlockView.LinkToObject.Default.Card.SmallIconCover -> view.copy(
isSelected = isSelected
)
is BlockView.LinkToObject.Default.Card.MediumIconCover -> view.copy(
isSelected = isSelected
)
is BlockView.LinkToObject.Archived -> view.copy(
@ -541,7 +550,10 @@ fun List<BlockView>.clearSearchHighlights(): List<BlockView> = map { view ->
is BlockView.Media.Bookmark -> view.copy(searchFields = emptyList())
is BlockView.Media.File -> view.copy(searchFields = emptyList())
is BlockView.LinkToObject.Default.Text -> view.copy(searchFields = emptyList())
is BlockView.LinkToObject.Default.Card -> view.copy(searchFields = emptyList())
is BlockView.LinkToObject.Default.Card.SmallIcon -> view.copy(searchFields = emptyList())
is BlockView.LinkToObject.Default.Card.MediumIcon -> view.copy(searchFields = emptyList())
is BlockView.LinkToObject.Default.Card.SmallIconCover -> view.copy(searchFields = emptyList())
is BlockView.LinkToObject.Default.Card.MediumIconCover -> view.copy(searchFields = emptyList())
is BlockView.LinkToObject.Archived -> view.copy(searchFields = emptyList())
else -> view.also { check(view !is BlockView.Searchable) }
}
@ -615,7 +627,19 @@ fun List<BlockView>.highlight(
val fields = listOf(DEFAULT_SEARCH_FIELD_KEY to view.text.orEmpty())
view.copy(searchFields = highlighter(fields))
}
is BlockView.LinkToObject.Default.Card -> {
is BlockView.LinkToObject.Default.Card.SmallIcon -> {
val fields = listOf(DEFAULT_SEARCH_FIELD_KEY to view.text.orEmpty())
view.copy(searchFields = highlighter(fields))
}
is BlockView.LinkToObject.Default.Card.MediumIcon -> {
val fields = listOf(DEFAULT_SEARCH_FIELD_KEY to view.text.orEmpty())
view.copy(searchFields = highlighter(fields))
}
is BlockView.LinkToObject.Default.Card.SmallIconCover -> {
val fields = listOf(DEFAULT_SEARCH_FIELD_KEY to view.text.orEmpty())
view.copy(searchFields = highlighter(fields))
}
is BlockView.LinkToObject.Default.Card.MediumIconCover -> {
val fields = listOf(DEFAULT_SEARCH_FIELD_KEY to view.text.orEmpty())
view.copy(searchFields = highlighter(fields))
}
@ -646,7 +670,10 @@ fun BlockView.setHighlight(
is BlockView.Media.Bookmark -> copy(searchFields = highlights)
is BlockView.Media.File -> copy(searchFields = highlights)
is BlockView.LinkToObject.Default.Text -> copy(searchFields = highlights)
is BlockView.LinkToObject.Default.Card -> copy(searchFields = highlights)
is BlockView.LinkToObject.Default.Card.SmallIcon -> copy(searchFields = highlights)
is BlockView.LinkToObject.Default.Card.MediumIcon -> copy(searchFields = highlights)
is BlockView.LinkToObject.Default.Card.SmallIconCover -> copy(searchFields = highlights)
is BlockView.LinkToObject.Default.Card.MediumIconCover -> copy(searchFields = highlights)
is BlockView.LinkToObject.Archived -> copy(searchFields = highlights)
else -> this.also { check(this !is BlockView.Searchable) }
}
@ -881,7 +908,10 @@ fun BlockView.updateSelection(newSelection: Boolean) = when (this) {
is BlockView.MediaPlaceholder.Video -> copy(isSelected = newSelection)
is BlockView.Error.Video -> copy(isSelected = newSelection)
is BlockView.LinkToObject.Default.Text -> copy(isSelected = newSelection)
is BlockView.LinkToObject.Default.Card -> copy(isSelected = newSelection)
is BlockView.LinkToObject.Default.Card.SmallIcon -> copy(isSelected = newSelection)
is BlockView.LinkToObject.Default.Card.MediumIcon -> copy(isSelected = newSelection)
is BlockView.LinkToObject.Default.Card.SmallIconCover -> copy(isSelected = newSelection)
is BlockView.LinkToObject.Default.Card.MediumIconCover -> copy(isSelected = newSelection)
is BlockView.LinkToObject.Archived -> copy(isSelected = newSelection)
is BlockView.LinkToObject.Deleted -> copy(isSelected = newSelection)
is BlockView.LinkToObject.Loading -> copy(isSelected = newSelection)

View file

@ -31,7 +31,10 @@ import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_LATEX
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_NUMBERED
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_ARCHIVE
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_CARD
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_CARD_MEDIUM_ICON
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_CARD_MEDIUM_ICON_COVER
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_CARD_SMALL_ICON
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_CARD_SMALL_ICON_COVER
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_DEFAULT
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_DELETED
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_OBJECT_LINK_LOADING
@ -61,7 +64,6 @@ import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_VIDEO_PLACEHOLDER
import com.anytypeio.anytype.presentation.editor.editor.model.types.Types.HOLDER_VIDEO_UPLOAD
import com.anytypeio.anytype.presentation.objects.ObjectIcon
import com.anytypeio.anytype.presentation.objects.appearance.choose.ObjectAppearanceChooseIconViewModel
import com.anytypeio.anytype.presentation.objects.appearance.choose.ObjectAppearanceChooseSettingsView
import com.anytypeio.anytype.presentation.relations.DocumentRelationView
@ -235,12 +237,19 @@ sealed class BlockView : ViewType {
val description: Description,
val showCover: Boolean,
val showType: Boolean,
val icon: Icon
) {
sealed interface Description {
object NONE : Description
object SNIPPET : Description
object RELATION : Description
}
sealed interface Icon {
object NONE : Icon
object SMALL : Icon
object MEDIUM : Icon
}
}
data class Menu(
@ -1053,7 +1062,7 @@ sealed class BlockView : ViewType {
* @property isDeleted this property determines whether this linked object is deleted or not.
* Whenever isDeleted is true, we don't care about isArchived flags
*/
sealed class Default : LinkToObject() {
sealed class Default : LinkToObject(), Searchable {
abstract val text: String?
abstract val description: String?
@ -1072,27 +1081,85 @@ sealed class BlockView : ViewType {
override val background: ThemeColor = ThemeColor.DEFAULT,
override val decorations: List<Decoration> = emptyList(),
override val objectTypeName: String? = null
) : Default(), Searchable {
) : Default() {
override fun getViewType() = HOLDER_OBJECT_LINK_DEFAULT
}
data class Card(
override val id: String,
override val indent: Int = 0,
override val isSelected: Boolean = false,
override val searchFields: List<Searchable.Field> = emptyList(),
override val text: String? = null,
override val description: String? = null,
override val icon: ObjectIcon,
override val background: ThemeColor,
override val decorations: List<Decoration> = emptyList(),
override val objectTypeName: String? = null,
val coverColor: CoverColor? = null,
val coverImage: Url? = null,
val coverGradient: String? = null,
val isPreviousBlockMedia: Boolean,
) : Default(), Searchable {
override fun getViewType() = HOLDER_OBJECT_LINK_CARD
sealed class Card: Default() {
abstract val isPreviousBlockMedia: Boolean
data class SmallIcon(
override val id: String,
override val indent: Int = 0,
override val isSelected: Boolean = false,
override val searchFields: List<Searchable.Field> = emptyList(),
override val text: String? = null,
override val description: String? = null,
override val icon: ObjectIcon,
override val background: ThemeColor,
override val decorations: List<Decoration> = emptyList(),
override val objectTypeName: String? = null,
override val isPreviousBlockMedia: Boolean
) : Card() {
override fun getViewType() = HOLDER_OBJECT_LINK_CARD_SMALL_ICON
}
data class MediumIcon(
override val id: String,
override val indent: Int = 0,
override val isSelected: Boolean = false,
override val searchFields: List<Searchable.Field> = emptyList(),
override val text: String? = null,
override val description: String? = null,
override val icon: ObjectIcon,
override val background: ThemeColor,
override val decorations: List<Decoration> = emptyList(),
override val objectTypeName: String? = null,
override val isPreviousBlockMedia: Boolean
) : Card() {
override fun getViewType() = HOLDER_OBJECT_LINK_CARD_MEDIUM_ICON
}
data class SmallIconCover(
override val id: String,
override val indent: Int = 0,
override val isSelected: Boolean = false,
override val searchFields: List<Searchable.Field> = emptyList(),
override val text: String? = null,
override val description: String? = null,
override val icon: ObjectIcon,
override val background: ThemeColor,
override val decorations: List<Decoration> = emptyList(),
override val objectTypeName: String? = null,
override val isPreviousBlockMedia: Boolean,
val cover : Cover?
) : Card() {
override fun getViewType() = HOLDER_OBJECT_LINK_CARD_SMALL_ICON_COVER
}
data class MediumIconCover(
override val id: String,
override val indent: Int = 0,
override val isSelected: Boolean = false,
override val searchFields: List<Searchable.Field> = emptyList(),
override val text: String? = null,
override val description: String? = null,
override val icon: ObjectIcon,
override val background: ThemeColor,
override val decorations: List<Decoration> = emptyList(),
override val objectTypeName: String? = null,
override val isPreviousBlockMedia: Boolean,
val cover : Cover?
) : Card() {
override fun getViewType() = HOLDER_OBJECT_LINK_CARD_MEDIUM_ICON_COVER
}
sealed class Cover {
data class Color(val color: CoverColor) : Cover()
data class Image(val url: Url) : Cover()
data class Gradient(val gradient: String) : Cover()
}
}
}

View file

@ -15,11 +15,14 @@ object Types {
const val HOLDER_NUMBERED = 9
const val HOLDER_TOGGLE = 10
const val HOLDER_OBJECT_LINK_DEFAULT = 13
const val HOLDER_OBJECT_LINK_CARD = 52
const val HOLDER_OBJECT_LINK_ARCHIVE = 14
const val HOLDER_OBJECT_LINK_DELETED = 15
const val HOLDER_OBJECT_LINK_LOADING = 53
const val HOLDER_OBJECT_LINK_DEFAULT = 501
const val HOLDER_OBJECT_LINK_ARCHIVE = 502
const val HOLDER_OBJECT_LINK_DELETED = 503
const val HOLDER_OBJECT_LINK_LOADING = 504
const val HOLDER_OBJECT_LINK_CARD_SMALL_ICON = 505
const val HOLDER_OBJECT_LINK_CARD_MEDIUM_ICON = 506
const val HOLDER_OBJECT_LINK_CARD_SMALL_ICON_COVER = 507
const val HOLDER_OBJECT_LINK_CARD_MEDIUM_ICON_COVER = 508
const val HOLDER_HIGHLIGHT = 17

View file

@ -10,6 +10,7 @@ import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Relation
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.SmartBlockType
import com.anytypeio.anytype.core_models.ThemeColor
import com.anytypeio.anytype.core_models.Url
import com.anytypeio.anytype.core_models.ext.parseThemeTextColor
import com.anytypeio.anytype.core_models.ext.textColor
@ -1653,7 +1654,7 @@ class DefaultBlockViewRenderer @Inject constructor(
val factory = LinkAppearanceFactory(content, obj.layout)
val inEditorAppearance = factory.createInEditorLinkAppearance()
val isCard = inEditorAppearance.isCard
val icon = if (inEditorAppearance.showIcon) {
val objectIcon = if (inEditorAppearance.showIcon) {
ObjectIcon.getEditorLinkToObjectIcon(
obj = obj,
layout = obj.layout,
@ -1662,6 +1663,7 @@ class DefaultBlockViewRenderer @Inject constructor(
} else {
ObjectIcon.None
}
val name = obj.getProperObjectName()
val description = when (inEditorAppearance.description) {
@ -1669,6 +1671,7 @@ class DefaultBlockViewRenderer @Inject constructor(
InEditor.Description.RELATION -> obj.description
InEditor.Description.SNIPPET -> obj.snippet
}
val objectTypeName = if (inEditorAppearance.showType) {
val typeUrl = obj.type.firstOrNull()
objectTypes.find { it.url == typeUrl }?.name
@ -1676,89 +1679,185 @@ class DefaultBlockViewRenderer @Inject constructor(
null
}
val isSelected = checkIfSelected(
mode = mode,
block = block,
selection = selection
)
val background = block.parseThemeBackgroundColor()
return if (isCard) {
var coverColor: CoverColor? = null
var coverImage: Url? = null
var coverGradient: String? = null
if (inEditorAppearance.showCover) {
when (obj.coverType) {
CoverType.UPLOADED_IMAGE -> {
coverImage = obj.coverId?.let { id ->
urlBuilder.image(id)
}
}
CoverType.BUNDLED_IMAGE -> {
val hash = obj.coverId?.let { id ->
coverImageHashProvider.provide(id)
}
if (hash != null) coverImage = urlBuilder.image(hash)
}
CoverType.COLOR -> {
coverColor = obj.coverId?.let { id ->
CoverColor.values().find { it.code == id }
}
}
CoverType.GRADIENT -> {
coverGradient = obj.coverId
}
else -> Timber.d("Missing cover type: ${obj.coverType?.name}")
}
}
BlockView.LinkToObject.Default.Card(
val decorations = buildNestedDecorationData(
block = block,
parentScheme = parentSchema,
currentDecoration = DecorationData(
style = DecorationData.Style.Card,
background = block.parseThemeBackgroundColor()
)
).toBlockViewDecoration(block)
linkToObjectCard(
id = block.id,
icon = icon,
text = name,
description = description,
name = name,
objectIcon = objectIcon,
indent = indent,
isSelected = checkIfSelected(
mode = mode,
block = block,
selection = selection
),
coverColor = coverColor,
coverImage = coverImage,
coverGradient = coverGradient,
background = block.parseThemeBackgroundColor(),
obj = obj,
isSelected = isSelected,
isPreviousBlockMedia = isPreviousBlockMedia,
objectTypeName = objectTypeName,
decorations = buildNestedDecorationData(
block = block,
parentScheme = parentSchema,
currentDecoration = DecorationData(
style = DecorationData.Style.Card,
background = block.parseThemeBackgroundColor()
)
).toBlockViewDecoration(block)
description = description,
inEditorAppearance = inEditorAppearance,
background = background,
decorations = decorations,
objectTypeName = objectTypeName
)
} else {
val decorations = buildNestedDecorationData(
block = block,
parentScheme = parentSchema,
currentDecoration = DecorationData(
style = DecorationData.Style.None,
background = block.parseThemeBackgroundColor()
)
).toBlockViewDecoration(block)
BlockView.LinkToObject.Default.Text(
id = block.id,
icon = icon,
icon = objectIcon,
text = name,
indent = indent,
isSelected = checkIfSelected(
mode = mode,
block = block,
selection = selection
),
background = block.parseThemeBackgroundColor(),
decorations = buildNestedDecorationData(
block = block,
parentScheme = parentSchema,
currentDecoration = DecorationData(
style = DecorationData.Style.None,
background = block.parseThemeBackgroundColor()
)
).toBlockViewDecoration(block),
isSelected = isSelected,
background = background,
decorations = decorations,
description = description,
objectTypeName = objectTypeName
)
}
}
private fun linkToObjectCardCover(
obj: ObjectWrapper.Basic,
urlBuilder: UrlBuilder
): BlockView.LinkToObject.Default.Card.Cover? {
return when (obj.coverType) {
CoverType.UPLOADED_IMAGE -> {
val url = obj.coverId?.let { id -> urlBuilder.image(id) }
if (url != null) {
BlockView.LinkToObject.Default.Card.Cover.Image(url = url)
} else {
null
}
}
CoverType.BUNDLED_IMAGE -> {
val hash = obj.coverId?.let { id ->
coverImageHashProvider.provide(id)
}
if (hash != null) {
BlockView.LinkToObject.Default.Card.Cover.Image(url = urlBuilder.image(hash))
} else {
null
}
}
CoverType.COLOR -> {
val coverColor = obj.coverId?.let { id ->
CoverColor.values().find { it.code == id }
}
if (coverColor != null) {
BlockView.LinkToObject.Default.Card.Cover.Color(color = coverColor)
} else {
null
}
}
CoverType.GRADIENT -> {
val coverGradient = obj.coverId
if (coverGradient != null) {
BlockView.LinkToObject.Default.Card.Cover.Gradient(
gradient = coverGradient
)
} else {
null
}
}
else -> null
}
}
private fun linkToObjectCard(
id: Id,
name: String?,
objectIcon: ObjectIcon,
indent: Int,
obj: ObjectWrapper.Basic,
isSelected: Boolean,
isPreviousBlockMedia: Boolean,
description: String?,
inEditorAppearance: InEditor,
background: ThemeColor,
decorations: List<BlockView.Decoration>,
objectTypeName: String?
): BlockView.LinkToObject.Default.Card {
val isWithCover = inEditorAppearance.showCover
val iconSize = inEditorAppearance.icon
return if (isWithCover) {
val cover = linkToObjectCardCover(obj, urlBuilder)
if (obj.layout != ObjectType.Layout.TODO && iconSize == InEditor.Icon.MEDIUM) {
BlockView.LinkToObject.Default.Card.MediumIconCover(
id = id,
text = name,
icon = objectIcon,
indent = indent,
isSelected = isSelected,
description = description,
background = background,
decorations = decorations,
objectTypeName = objectTypeName,
isPreviousBlockMedia = isPreviousBlockMedia,
cover = cover
)
} else {
BlockView.LinkToObject.Default.Card.SmallIconCover(
id = id,
text = name,
icon = objectIcon,
indent = indent,
isSelected = isSelected,
description = description,
background = background,
decorations = decorations,
objectTypeName = objectTypeName,
isPreviousBlockMedia = isPreviousBlockMedia,
cover = cover
)
}
} else {
if (iconSize == InEditor.Icon.MEDIUM) {
BlockView.LinkToObject.Default.Card.MediumIcon(
id = id,
text = name,
icon = objectIcon,
indent = indent,
isSelected = isSelected,
description = description,
background = background,
decorations = decorations,
objectTypeName = objectTypeName,
isPreviousBlockMedia = isPreviousBlockMedia
)
} else {
BlockView.LinkToObject.Default.Card.SmallIcon(
id = id,
text = name,
icon = objectIcon,
indent = indent,
isSelected = isSelected,
description = description,
background = background,
decorations = decorations,
objectTypeName = objectTypeName,
isPreviousBlockMedia = isPreviousBlockMedia
)
}
}
}
private fun linkArchive(
block: Block,
indent: Int,

View file

@ -18,9 +18,8 @@ internal class LinkAppearanceFactory(
private val isNoteLayout = layout == ObjectType.Layout.NOTE
private val withDescription = !isNoteLayout
//todo Cover menu option is off. No proper design yet.
private val canHaveCover: Boolean =
false && !isNoteLayout && content.cardStyle != CardStyle.TEXT
!isNoteLayout && content.cardStyle != CardStyle.TEXT
private val withCover = canHaveCover && (content.hasCover)
@ -37,14 +36,19 @@ internal class LinkAppearanceFactory(
Block.Content.Link.Description.ADDED -> InEditor.Description.RELATION
Block.Content.Link.Description.CONTENT -> InEditor.Description.SNIPPET
}
}
val icon = when (content.iconSize) {
IconSize.NONE -> InEditor.Icon.NONE
IconSize.SMALL -> InEditor.Icon.SMALL
IconSize.MEDIUM -> InEditor.Icon.MEDIUM
}
return InEditor(
showIcon = withIcon,
isCard = content.cardStyle == CardStyle.CARD,
description = description,
showCover = withCover,
showType = content.hasType
showType = content.hasType,
icon = icon
)
}

View file

@ -34,10 +34,18 @@ class ObjectAppearanceChoosePreviewLayoutViewModel(
oldContent: Block.Content.Link
): Block.Content.Link {
return when (item) {
is ObjectAppearanceChooseSettingsView.PreviewLayout.Text ->
is ObjectAppearanceChooseSettingsView.PreviewLayout.Text -> {
val oldIconSize = oldContent.iconSize
val newIconSize = if (oldIconSize == Block.Content.Link.IconSize.MEDIUM) {
Block.Content.Link.IconSize.SMALL
} else {
oldIconSize
}
oldContent.copy(
cardStyle = Block.Content.Link.CardStyle.TEXT
cardStyle = Block.Content.Link.CardStyle.TEXT,
iconSize = newIconSize
)
}
is ObjectAppearanceChooseSettingsView.PreviewLayout.Card ->
oldContent.copy(
cardStyle = Block.Content.Link.CardStyle.CARD

View file

@ -2768,16 +2768,13 @@ class DefaultBlockViewRendererTest {
image = null,
mode = BlockView.Mode.EDIT
),
BlockView.LinkToObject.Default.Card(
BlockView.LinkToObject.Default.Card.SmallIcon(
id = a.id,
icon = ObjectIcon.None,
text = name,
description = "",
indent = 0,
isSelected = false,
coverColor = null,
coverImage = null,
coverGradient = null,
background = a.parseThemeBackgroundColor(),
isPreviousBlockMedia = false,
objectTypeName = null,

View file

@ -32,6 +32,7 @@ class LinkAppearanceInEditorTest {
description = Description.NONE,
showCover = false,
showType = false,
icon = BlockView.Appearance.InEditor.Icon.NONE
)
assertEquals(expected, actual)
}
@ -50,6 +51,7 @@ class LinkAppearanceInEditorTest {
description = Description.NONE,
showCover = false,
showType = false,
icon = BlockView.Appearance.InEditor.Icon.NONE
)
assertEquals(expected, actual)
@ -72,6 +74,7 @@ class LinkAppearanceInEditorTest {
description = Description.NONE,
showCover = false,
showType = false,
icon = BlockView.Appearance.InEditor.Icon.NONE
)
assertEquals(expected, actual)
@ -92,6 +95,7 @@ class LinkAppearanceInEditorTest {
description = Description.NONE,
showCover = false,
showType = false,
icon = BlockView.Appearance.InEditor.Icon.NONE
)
assertEquals(expected, actual)
@ -114,6 +118,7 @@ class LinkAppearanceInEditorTest {
description = Description.NONE,
showCover = false,
showType = false,
icon = BlockView.Appearance.InEditor.Icon.SMALL
)
assertEquals(expected, actual)
@ -136,6 +141,7 @@ class LinkAppearanceInEditorTest {
description = Description.NONE,
showCover = false,
showType = false,
icon = BlockView.Appearance.InEditor.Icon.NONE
)
assertEquals(expected, actual)
@ -159,6 +165,7 @@ class LinkAppearanceInEditorTest {
description = Description.RELATION,
showCover = false,
showType = false,
icon = BlockView.Appearance.InEditor.Icon.NONE
)
assertEquals(expected, actual)
@ -182,6 +189,7 @@ class LinkAppearanceInEditorTest {
description = Description.SNIPPET,
showCover = false,
showType = false,
icon = BlockView.Appearance.InEditor.Icon.NONE
)
assertEquals(expected, actual)
@ -205,6 +213,7 @@ class LinkAppearanceInEditorTest {
description = Description.RELATION,
showCover = false,
showType = false,
icon = BlockView.Appearance.InEditor.Icon.NONE
)
assertEquals(expected, actual)

View file

@ -95,7 +95,7 @@ class LinkAppearanceMenuTest {
val expected = BlockView.Appearance.Menu(
preview = MenuItem.PreviewLayout.CARD,
icon = MenuItem.Icon.SMALL,
cover = null,
cover = MenuItem.Cover.WITHOUT,
description = MenuItem.Description.ADDED,
objectType = MenuItem.ObjectType.WITHOUT,
iconMenus = listOf(

View file

@ -0,0 +1,104 @@
package com.anytypeio.anytype.presentation.objects.appearance.choose
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.domain.base.Either
import com.anytypeio.anytype.domain.block.interactor.SetLinkAppearance
import com.anytypeio.anytype.presentation.editor.Editor
import com.anytypeio.anytype.presentation.util.CoroutinesTestRule
import com.anytypeio.anytype.presentation.util.Dispatcher
import com.anytypeio.anytype.test_utils.MockDataFactory
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.stub
import org.mockito.kotlin.times
import org.mockito.kotlin.verifyBlocking
class ObjectAppearanceChoosePreviewLayoutViewModelTest {
@get:Rule
val rule = InstantTaskExecutorRule()
@get:Rule
val coroutineTestRule = CoroutinesTestRule()
@Mock
lateinit var dispatcher: Dispatcher<Payload>
@Mock
lateinit var setLinkAppearance: SetLinkAppearance
private lateinit var viewModel: ObjectAppearanceChoosePreviewLayoutViewModel
private var storage = Editor.Storage()
@Before
fun init() {
MockitoAnnotations.openMocks(this)
viewModel = ObjectAppearanceChoosePreviewLayoutViewModel(
storage = storage,
setLinkAppearance = setLinkAppearance,
dispatcher = dispatcher
)
}
@Test
fun `should fallback to icon size small when changing from card preview to text`() {
val root = MockDataFactory.randomUuid()
val target = MockDataFactory.randomUuid()
val block = Block(
id = MockDataFactory.randomUuid(),
children = listOf(),
content = Block.Content.Link(
target = target,
type = Block.Content.Link.Type.PAGE,
iconSize = Block.Content.Link.IconSize.MEDIUM,
cardStyle = Block.Content.Link.CardStyle.CARD,
description = Block.Content.Link.Description.ADDED,
relations = setOf()
),
fields = Block.Fields.empty()
)
setLinkAppearance.stub {
onBlocking { invoke(any()) } doReturn Either.Right(
Payload(context = root, events = listOf())
)
}
storage.document.update(document = listOf(block))
viewModel.onItemClicked(
item = ObjectAppearanceChooseSettingsView.PreviewLayout.Text(isSelected = false),
ctx = root,
blockId = block.id
)
val params = SetLinkAppearance.Params(
contextId = root,
content = Block.Content.Link(
target = target,
type = Block.Content.Link.Type.PAGE,
iconSize = Block.Content.Link.IconSize.SMALL,
cardStyle = Block.Content.Link.CardStyle.TEXT,
description = Block.Content.Link.Description.ADDED,
relations = setOf()
),
blockId = block.id
)
verifyBlocking(setLinkAppearance, times(1)) {
invoke(params)
}
coroutineTestRule.advanceTime(100)
}
}