mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
Editor | Enhancement | Support new link appearance api (#2329)
This commit is contained in:
parent
0ddc5014f1
commit
f89bfb6146
50 changed files with 1085 additions and 1061 deletions
|
@ -23,6 +23,7 @@ import com.anytypeio.anytype.domain.block.interactor.MergeBlocks
|
|||
import com.anytypeio.anytype.domain.block.interactor.Move
|
||||
import com.anytypeio.anytype.domain.block.interactor.RemoveLinkMark
|
||||
import com.anytypeio.anytype.domain.block.interactor.ReplaceBlock
|
||||
import com.anytypeio.anytype.domain.block.interactor.SetLinkAppearance
|
||||
import com.anytypeio.anytype.domain.block.interactor.SetObjectType
|
||||
import com.anytypeio.anytype.domain.block.interactor.SplitBlock
|
||||
import com.anytypeio.anytype.domain.block.interactor.TurnIntoDocument
|
||||
|
@ -727,6 +728,13 @@ object EditorUseCaseModule {
|
|||
repo: BlockRepository
|
||||
): UpdateFields = UpdateFields(repo)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerScreen
|
||||
fun provideSetLinkAppearance(
|
||||
repo: BlockRepository
|
||||
): SetLinkAppearance = SetLinkAppearance(repo)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerScreen
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.anytypeio.anytype.di.feature
|
|||
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerModal
|
||||
import com.anytypeio.anytype.domain.block.interactor.UpdateFields
|
||||
import com.anytypeio.anytype.domain.block.interactor.SetLinkAppearance
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectAppearanceSettingViewModel
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.ObjectAppearanceCoverViewModel
|
||||
|
@ -38,12 +38,12 @@ object ObjectAppearanceSettingModule {
|
|||
@PerModal
|
||||
fun provideObjectAppearanceSettingViewModelFactory(
|
||||
storage: Editor.Storage,
|
||||
updateFields: UpdateFields,
|
||||
setLinkAppearance: SetLinkAppearance,
|
||||
dispatcher: Dispatcher<Payload>
|
||||
): ObjectAppearanceSettingViewModel.Factory {
|
||||
return ObjectAppearanceSettingViewModel.Factory(
|
||||
storage = storage,
|
||||
updateFields = updateFields,
|
||||
setLinkAppearance = setLinkAppearance,
|
||||
dispatcher = dispatcher
|
||||
)
|
||||
}
|
||||
|
@ -71,12 +71,12 @@ object ObjectAppearanceIconModule {
|
|||
@PerModal
|
||||
fun provideObjectAppearanceIconViewModelFactory(
|
||||
storage: Editor.Storage,
|
||||
updateFields: UpdateFields,
|
||||
setLinkAppearance: SetLinkAppearance,
|
||||
dispatcher: Dispatcher<Payload>
|
||||
): ObjectAppearanceIconViewModel.Factory {
|
||||
return ObjectAppearanceIconViewModel.Factory(
|
||||
storage = storage,
|
||||
updateFields = updateFields,
|
||||
setLinkAppearance = setLinkAppearance,
|
||||
dispatcher = dispatcher
|
||||
)
|
||||
}
|
||||
|
@ -104,12 +104,12 @@ object ObjectAppearancePreviewLayoutModule {
|
|||
@PerModal
|
||||
fun provideObjectAppearancePreviewLayoutViewModelFactory(
|
||||
storage: Editor.Storage,
|
||||
updateFields: UpdateFields,
|
||||
setLinkAppearance: SetLinkAppearance,
|
||||
dispatcher: Dispatcher<Payload>
|
||||
): ObjectAppearancePreviewLayoutViewModel.Factory {
|
||||
return ObjectAppearancePreviewLayoutViewModel.Factory(
|
||||
storage = storage,
|
||||
updateFields = updateFields,
|
||||
setLinkAppearance = setLinkAppearance,
|
||||
dispatcher = dispatcher
|
||||
)
|
||||
}
|
||||
|
@ -137,12 +137,12 @@ object ObjectAppearanceCoverModule {
|
|||
@PerModal
|
||||
fun provideObjectAppearanceCoverViewModelFactory(
|
||||
storage: Editor.Storage,
|
||||
updateFields: UpdateFields,
|
||||
setLinkAppearance: SetLinkAppearance,
|
||||
dispatcher: Dispatcher<Payload>
|
||||
): ObjectAppearanceCoverViewModel.Factory {
|
||||
return ObjectAppearanceCoverViewModel.Factory(
|
||||
storage = storage,
|
||||
updateFields = updateFields,
|
||||
setLinkAppearance = setLinkAppearance,
|
||||
dispatcher = dispatcher
|
||||
)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import com.anytypeio.anytype.core_utils.ext.toast
|
|||
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
|
||||
import com.anytypeio.anytype.databinding.FragmentObjAppearanceBaseBinding
|
||||
import com.anytypeio.anytype.di.common.componentManager
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectAppearanceSettingView
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.ObjectAppearanceCoverViewModel
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.ObjectAppearanceIconViewModel
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.ObjectAppearancePreviewLayoutViewModel
|
||||
|
@ -34,7 +35,10 @@ class ObjectAppearanceIconFragment : BaseBottomSheetFragment<FragmentObjAppearan
|
|||
private val adapterAppearance by lazy {
|
||||
ObjectAppearanceSettingAdapter(
|
||||
onItemClick = { item ->
|
||||
vm.onItemClicked(item = item, blockId = block, ctx = ctx)
|
||||
val icon = requireNotNull(item as? ObjectAppearanceSettingView.Icon) {
|
||||
"item $item must be Icon"
|
||||
}
|
||||
vm.onItemClicked(item = icon, blockId = block, ctx = ctx)
|
||||
},
|
||||
onSettingToggleChanged = { _, _ -> }
|
||||
)
|
||||
|
@ -119,7 +123,10 @@ class ObjectAppearancePreviewLayoutFragment :
|
|||
private val adapterAppearance by lazy {
|
||||
ObjectAppearanceSettingAdapter(
|
||||
onItemClick = { item ->
|
||||
vm.onItemClicked(item = item, blockId = block, ctx = ctx)
|
||||
val preview = requireNotNull(item as? ObjectAppearanceSettingView.PreviewLayout) {
|
||||
"item $item must be PreviewLayout"
|
||||
}
|
||||
vm.onItemClicked(item = preview, blockId = block, ctx = ctx)
|
||||
},
|
||||
onSettingToggleChanged = { _, _ -> }
|
||||
)
|
||||
|
@ -200,7 +207,10 @@ class ObjectAppearanceCoverFragment : BaseBottomSheetFragment<FragmentObjAppeara
|
|||
private val adapterAppearance by lazy {
|
||||
ObjectAppearanceSettingAdapter(
|
||||
onItemClick = { item ->
|
||||
vm.onItemClicked(item = item, blockId = block, ctx = ctx)
|
||||
val cover = requireNotNull(item as? ObjectAppearanceSettingView.Cover) {
|
||||
"item $item must be Cover"
|
||||
}
|
||||
vm.onItemClicked(item = cover, blockId = block, ctx = ctx)
|
||||
},
|
||||
onSettingToggleChanged = { _, _ -> }
|
||||
)
|
||||
|
|
|
@ -19,6 +19,7 @@ import com.anytypeio.anytype.core_utils.ext.toast
|
|||
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
|
||||
import com.anytypeio.anytype.databinding.FragmentObjectAppearanceSettingBinding
|
||||
import com.anytypeio.anytype.di.common.componentManager
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectAppearanceSettingView
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectAppearanceSettingViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -34,7 +35,11 @@ class ObjectAppearanceSettingFragment : BaseBottomSheetFragment<FragmentObjectAp
|
|||
ObjectAppearanceSettingAdapter(
|
||||
onItemClick = vm::onItemClicked,
|
||||
onSettingToggleChanged = { item, isChecked ->
|
||||
vm.onToggleClicked(item = item, blockId = block, ctx = ctx, isChecked = isChecked)
|
||||
val relation = requireNotNull(item as? ObjectAppearanceSettingView.Relation.Description) {
|
||||
"item $item must be Description"
|
||||
}
|
||||
|
||||
vm.onToggleClicked(description = relation, blockId = block, ctx = ctx, isChecked = isChecked)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -60,20 +60,6 @@ data class Block(
|
|||
else -> null
|
||||
}
|
||||
|
||||
val withName: Boolean? by default
|
||||
val withDescription: Boolean? by default
|
||||
val withIcon: Boolean? by default
|
||||
val withCover: Boolean? by default
|
||||
|
||||
/**
|
||||
* 0.0 - text, 1.0 - card
|
||||
*/
|
||||
val style: Double? by default
|
||||
|
||||
/**
|
||||
* 1.0 - small, 2.0 - medium, 3.0 - large
|
||||
*/
|
||||
val iconSize: Double? by default
|
||||
|
||||
val analyticsContext: String? by default
|
||||
|
||||
|
@ -81,13 +67,7 @@ data class Block(
|
|||
fun empty(): Fields = Fields(emptyMap())
|
||||
const val NAME_KEY = "name"
|
||||
const val TYPE_KEY = "type"
|
||||
const val ICON_SIZE_KEY = "iconSize"
|
||||
const val ICON_WITH_KEY = "withIcon"
|
||||
const val IS_LOCKED_KEY = "isLocked"
|
||||
const val COVER_WITH_KEY = "withCover"
|
||||
const val STYLE_KEY = "style"
|
||||
const val WITH_NAME_KEY = "withName"
|
||||
const val WITH_DESCRIPTION_KEY = "withDescription"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,12 +186,38 @@ data class Block(
|
|||
* @property type type of the link
|
||||
* @property fields fields storing additional properties
|
||||
*/
|
||||
//
|
||||
data class Link(
|
||||
val target: Id,
|
||||
val type: Type,
|
||||
val fields: Fields
|
||||
val iconSize: IconSize,
|
||||
val cardStyle: CardStyle,
|
||||
val description: Description,
|
||||
val relations: Set<Relation>,
|
||||
) : Content() {
|
||||
sealed interface Relation {
|
||||
object COVER : Relation
|
||||
object NAME : Relation
|
||||
object TYPE : Relation
|
||||
data class UNKNOWN(val value: String) : Relation
|
||||
}
|
||||
|
||||
enum class Type { PAGE, DATA_VIEW, DASHBOARD, ARCHIVE }
|
||||
enum class IconSize { NONE, SMALL, MEDIUM }
|
||||
enum class CardStyle { TEXT, CARD, INLINE }
|
||||
enum class Description { NONE, ADDED, CONTENT }
|
||||
|
||||
val hasDescription: Boolean
|
||||
get() = description != Description.NONE
|
||||
|
||||
val hasName: Boolean
|
||||
get() = relations.contains(Relation.NAME)
|
||||
|
||||
val hasCover: Boolean
|
||||
get() = relations.contains(Relation.COVER)
|
||||
|
||||
val hasType: Boolean
|
||||
get() = relations.contains(Relation.TYPE)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -79,7 +79,7 @@ sealed class Command {
|
|||
data class UpdateBlocksMark(
|
||||
val context: Id,
|
||||
val targets: List<Id>,
|
||||
val mark : Block.Content.Text.Mark
|
||||
val mark: Block.Content.Text.Mark
|
||||
)
|
||||
|
||||
/**
|
||||
|
@ -236,7 +236,7 @@ sealed class Command {
|
|||
* @property key relation key
|
||||
*/
|
||||
data class SetRelationKey(
|
||||
val contextId : Id,
|
||||
val contextId: Id,
|
||||
val blockId: Id,
|
||||
val key: Id
|
||||
)
|
||||
|
@ -355,4 +355,10 @@ sealed class Command {
|
|||
val context: Id,
|
||||
val fields: List<Pair<Id, Block.Fields>>
|
||||
)
|
||||
|
||||
data class SetLinkAppearance(
|
||||
val contextId: String,
|
||||
val blockId: String,
|
||||
val content: Block.Content.Link
|
||||
)
|
||||
}
|
|
@ -83,7 +83,10 @@ sealed class Event {
|
|||
override val context: String,
|
||||
val id: Id,
|
||||
val target: Id,
|
||||
val fields: Block.Fields?
|
||||
val iconSize: Block.Content.Link.IconSize?,
|
||||
val cardStyle: Block.Content.Link.CardStyle?,
|
||||
val description: Block.Content.Link.Description?,
|
||||
val relations: Set<Block.Content.Link.Relation>?,
|
||||
) : Command()
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,9 +14,8 @@ import com.anytypeio.anytype.core_ui.databinding.ItemObjectPreviewSettingBinding
|
|||
import com.anytypeio.anytype.core_utils.ext.gone
|
||||
import com.anytypeio.anytype.core_utils.ext.invisible
|
||||
import com.anytypeio.anytype.core_utils.ext.visible
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.Companion.LINK_STYLE_CARD
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.MenuItem
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectAppearanceSettingView
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.ObjectAppearanceIconState
|
||||
|
||||
class ObjectAppearanceSettingAdapter(
|
||||
private val onItemClick: (ObjectAppearanceSettingView) -> Unit,
|
||||
|
@ -163,10 +162,9 @@ class ObjectAppearanceSettingAdapter(
|
|||
|
||||
fun bind(item: ObjectAppearanceSettingView.Settings.PreviewLayout) = with(binding) {
|
||||
settingName.text = itemView.context.getString(R.string.preview_layout)
|
||||
settingValue.text = if (item.style == LINK_STYLE_CARD) {
|
||||
itemView.context.getString(R.string.card)
|
||||
} else {
|
||||
itemView.context.getString(R.string.text)
|
||||
settingValue.text = when (item.previewLayoutState) {
|
||||
MenuItem.PreviewLayout.TEXT -> itemView.context.getString(R.string.text)
|
||||
MenuItem.PreviewLayout.CARD -> itemView.context.getString(R.string.card)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,12 +177,10 @@ class ObjectAppearanceSettingAdapter(
|
|||
|
||||
fun bind(item: ObjectAppearanceSettingView.Settings.Icon) = with(binding) {
|
||||
settingName.text = itemView.context.getString(R.string.icon)
|
||||
settingValue.text = when (item.state) {
|
||||
ObjectAppearanceIconState.NONE -> itemView.context.getString(R.string.none)
|
||||
ObjectAppearanceIconState.SMALL -> itemView.context.getString(R.string.small)
|
||||
ObjectAppearanceIconState.MEDIUM -> itemView.context.getString(R.string.medium)
|
||||
ObjectAppearanceIconState.LARGE -> itemView.context.getString(R.string.large)
|
||||
ObjectAppearanceIconState.UNKNOWN -> itemView.context.getString(R.string.unknown)
|
||||
settingValue.text = when (item.icon) {
|
||||
MenuItem.Icon.NONE -> itemView.context.getString(R.string.none)
|
||||
MenuItem.Icon.SMALL -> itemView.context.getString(R.string.small)
|
||||
MenuItem.Icon.MEDIUM -> itemView.context.getString(R.string.medium)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -197,10 +193,9 @@ class ObjectAppearanceSettingAdapter(
|
|||
|
||||
fun bind(item: ObjectAppearanceSettingView.Settings.Cover) = with(binding) {
|
||||
settingName.text = itemView.context.getString(R.string.cover)
|
||||
settingValue.text = if (item.withCover == true) {
|
||||
itemView.context.getString(R.string.visible)
|
||||
} else {
|
||||
itemView.context.getString(R.string.none)
|
||||
settingValue.text = when (item.coverState) {
|
||||
MenuItem.Cover.WITH -> itemView.context.getString(R.string.visible)
|
||||
MenuItem.Cover.WITHOUT -> itemView.context.getString(R.string.none)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -228,12 +223,16 @@ class ObjectAppearanceSettingAdapter(
|
|||
is ObjectAppearanceSettingView.Relation.Description -> {
|
||||
relIcon.setImageResource(R.drawable.ic_relation_description)
|
||||
relName.text = itemView.context.getString(R.string.description)
|
||||
relSwitch.isChecked = item.withDescription ?: false
|
||||
relSwitch.visible()
|
||||
relSwitch.isChecked = when (item.description) {
|
||||
MenuItem.Description.WITH -> true
|
||||
MenuItem.Description.WITHOUT -> false
|
||||
}
|
||||
}
|
||||
is ObjectAppearanceSettingView.Relation.Name -> {
|
||||
relIcon.setImageResource(R.drawable.ic_relation_name)
|
||||
relName.text = itemView.context.getString(R.string.name)
|
||||
relSwitch.isChecked = item.withName ?: false
|
||||
relSwitch.gone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -243,11 +242,6 @@ class ObjectAppearanceSettingAdapter(
|
|||
|
||||
fun bind(item: ObjectAppearanceSettingView.Icon) = with(binding) {
|
||||
when (item) {
|
||||
is ObjectAppearanceSettingView.Icon.Large -> {
|
||||
tvSize.text = itemView.context.getString(R.string.large)
|
||||
ivIcon.gone()
|
||||
if (item.isSelected) ivCheckbox.visible() else ivCheckbox.invisible()
|
||||
}
|
||||
is ObjectAppearanceSettingView.Icon.Medium -> {
|
||||
tvSize.text = itemView.context.getString(R.string.medium)
|
||||
ivIcon.gone()
|
||||
|
|
|
@ -40,7 +40,7 @@ class BlockDataRepository(
|
|||
Result.Success(factory.remote.openObjectPreview(id))
|
||||
} catch (e: BackwardCompatilityNotSupportedException) {
|
||||
Result.Failure(Error.BackwardCompatibility)
|
||||
} catch (e : NotFoundObjectException) {
|
||||
} catch (e: NotFoundObjectException) {
|
||||
Result.Failure(Error.NotFoundObject)
|
||||
}
|
||||
|
||||
|
@ -105,6 +105,10 @@ class BlockDataRepository(
|
|||
command: Command.UpdateTextColor
|
||||
): Payload = factory.remote.updateTextColor(command)
|
||||
|
||||
override suspend fun setLinkAppearance(command: Command.SetLinkAppearance): Payload {
|
||||
return factory.remote.setLinkAppearance(command)
|
||||
}
|
||||
|
||||
override suspend fun updateBackgroundColor(
|
||||
command: Command.UpdateBackgroundColor
|
||||
): Payload = factory.remote.updateBackroundColor(command)
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.anytypeio.anytype.data.auth.repo.block
|
|||
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Command
|
||||
import com.anytypeio.anytype.core_models.Config
|
||||
import com.anytypeio.anytype.core_models.DVFilter
|
||||
import com.anytypeio.anytype.core_models.DVSort
|
||||
import com.anytypeio.anytype.core_models.DVViewer
|
||||
|
@ -37,6 +36,8 @@ interface BlockDataStore {
|
|||
suspend fun updateText(command: Command.UpdateText)
|
||||
suspend fun updateTextStyle(command: Command.UpdateStyle): Payload
|
||||
|
||||
suspend fun setLinkAppearance(command: Command.SetLinkAppearance): Payload
|
||||
|
||||
suspend fun updateCheckbox(command: Command.UpdateCheckbox): Payload
|
||||
suspend fun uploadBlock(command: Command.UploadBlock): Payload
|
||||
suspend fun move(command: Command.Move): Payload
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.anytypeio.anytype.data.auth.repo.block
|
|||
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Command
|
||||
import com.anytypeio.anytype.core_models.Config
|
||||
import com.anytypeio.anytype.core_models.DVFilter
|
||||
import com.anytypeio.anytype.core_models.DVSort
|
||||
import com.anytypeio.anytype.core_models.DVViewer
|
||||
|
@ -36,6 +35,8 @@ interface BlockRemote {
|
|||
suspend fun updateText(command: Command.UpdateText)
|
||||
suspend fun updateTextStyle(command: Command.UpdateStyle) : Payload
|
||||
|
||||
suspend fun setLinkAppearance(command: Command.SetLinkAppearance): Payload
|
||||
|
||||
suspend fun updateCheckbox(command: Command.UpdateCheckbox): Payload
|
||||
suspend fun move(command: Command.Move): Payload
|
||||
suspend fun createPage(
|
||||
|
|
|
@ -59,6 +59,10 @@ class BlockRemoteDataStore(private val remote: BlockRemote) : BlockDataStore {
|
|||
remote.updateText(command)
|
||||
}
|
||||
|
||||
override suspend fun setLinkAppearance(command: Command.SetLinkAppearance): Payload {
|
||||
return remote.setLinkAppearance(command)
|
||||
}
|
||||
|
||||
override suspend fun updateTextStyle(
|
||||
command: Command.UpdateStyle
|
||||
): Payload = remote.updateTextStyle(command)
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package com.anytypeio.anytype.domain.block.interactor
|
||||
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Command
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.domain.base.BaseUseCase
|
||||
import com.anytypeio.anytype.domain.base.Either
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
|
||||
class SetLinkAppearance(
|
||||
private val repository: BlockRepository,
|
||||
) : BaseUseCase<Payload, SetLinkAppearance.Params>() {
|
||||
|
||||
class Params(
|
||||
val contextId: String,
|
||||
val blockId: String,
|
||||
val content: Block.Content.Link
|
||||
)
|
||||
|
||||
override suspend fun run(params: Params): Either<Throwable, Payload> = safe {
|
||||
repository.setLinkAppearance(
|
||||
Command.SetLinkAppearance(
|
||||
contextId = params.contextId,
|
||||
blockId = params.blockId,
|
||||
content = params.content
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package com.anytypeio.anytype.domain.block.repo
|
|||
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Command
|
||||
import com.anytypeio.anytype.core_models.Config
|
||||
import com.anytypeio.anytype.core_models.DVFilter
|
||||
import com.anytypeio.anytype.core_models.DVRecord
|
||||
import com.anytypeio.anytype.core_models.DVSort
|
||||
|
@ -76,6 +75,7 @@ interface BlockRepository {
|
|||
suspend fun updateDocumentTitle(command: Command.UpdateTitle)
|
||||
suspend fun updateText(command: Command.UpdateText)
|
||||
suspend fun updateTextStyle(command: Command.UpdateStyle): Payload
|
||||
suspend fun setLinkAppearance(command: Command.SetLinkAppearance): Payload
|
||||
|
||||
suspend fun updateTextColor(command: Command.UpdateTextColor): Payload
|
||||
suspend fun updateBackgroundColor(command: Command.UpdateBackgroundColor): Payload
|
||||
|
@ -93,7 +93,7 @@ interface BlockRepository {
|
|||
template: Id?
|
||||
): Id
|
||||
|
||||
suspend fun openObjectPreview(id: Id) : Result<Payload>
|
||||
suspend fun openObjectPreview(id: Id): Result<Payload>
|
||||
|
||||
suspend fun openPage(id: String): Result<Payload>
|
||||
|
||||
|
@ -281,13 +281,13 @@ interface BlockRepository {
|
|||
suspend fun addToFeaturedRelations(ctx: Id, relations: List<Id>): Payload
|
||||
suspend fun removeFromFeaturedRelations(ctx: Id, relations: List<Id>): Payload
|
||||
|
||||
suspend fun setObjectIsFavorite(ctx: Id, isFavorite: Boolean) : Payload
|
||||
suspend fun setObjectIsArchived(ctx: Id, isArchived: Boolean) : Payload
|
||||
suspend fun setObjectIsFavorite(ctx: Id, isFavorite: Boolean): Payload
|
||||
suspend fun setObjectIsArchived(ctx: Id, isArchived: Boolean): Payload
|
||||
suspend fun setObjectListIsArchived(targets: List<Id>, isArchived: Boolean)
|
||||
|
||||
suspend fun deleteObjects(targets: List<Id>)
|
||||
|
||||
suspend fun setObjectLayout(ctx: Id, layout: ObjectType.Layout) : Payload
|
||||
suspend fun setObjectLayout(ctx: Id, layout: ObjectType.Layout): Payload
|
||||
|
||||
suspend fun clearFileCache()
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.anytypeio.anytype.middleware.block
|
|||
|
||||
import com.anytypeio.anytype.core_models.CBTextStyle
|
||||
import com.anytypeio.anytype.core_models.Command
|
||||
import com.anytypeio.anytype.core_models.Config
|
||||
import com.anytypeio.anytype.core_models.DVFilter
|
||||
import com.anytypeio.anytype.core_models.DVSort
|
||||
import com.anytypeio.anytype.core_models.DVViewer
|
||||
|
@ -76,6 +75,10 @@ class BlockMiddleware(
|
|||
)
|
||||
}
|
||||
|
||||
override suspend fun setLinkAppearance(command: Command.SetLinkAppearance): Payload {
|
||||
return middleware.blockLinkSetAppearance(command)
|
||||
}
|
||||
|
||||
override suspend fun uploadBlock(command: Command.UploadBlock): Payload =
|
||||
middleware.blockUpload(command)
|
||||
|
||||
|
@ -441,7 +444,7 @@ class BlockMiddleware(
|
|||
|
||||
override suspend fun addRelationToObject(
|
||||
ctx: Id, relation: Id
|
||||
) : Payload = middleware.objectRelationAdd(ctx, relation)
|
||||
): Payload = middleware.objectRelationAdd(ctx, relation)
|
||||
|
||||
override suspend fun addNewRelationToObject(
|
||||
ctx: Id,
|
||||
|
@ -527,7 +530,7 @@ class BlockMiddleware(
|
|||
isArchived = isArchived
|
||||
)
|
||||
|
||||
override suspend fun setObjectLayout(ctx: Id, layout: ObjectType.Layout) : Payload =
|
||||
override suspend fun setObjectLayout(ctx: Id, layout: ObjectType.Layout): Payload =
|
||||
middleware.objectSetLayout(ctx, layout)
|
||||
|
||||
override suspend fun clearFileCache() = middleware.fileListOffload()
|
||||
|
|
|
@ -34,7 +34,6 @@ import com.anytypeio.anytype.middleware.mappers.core
|
|||
import com.anytypeio.anytype.middleware.mappers.toCoreModels
|
||||
import com.anytypeio.anytype.middleware.mappers.toMiddlewareModel
|
||||
import com.anytypeio.anytype.middleware.mappers.toPayload
|
||||
import com.anytypeio.anytype.middleware.model.CreateAccountResponse
|
||||
import com.anytypeio.anytype.middleware.model.CreateWalletResponse
|
||||
import com.anytypeio.anytype.middleware.service.MiddlewareService
|
||||
import timber.log.Timber
|
||||
|
@ -62,7 +61,7 @@ class Middleware(
|
|||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun accountDelete() : AccountStatus {
|
||||
fun accountDelete(): AccountStatus {
|
||||
val request = Rpc.Account.Delete.Request(
|
||||
revert = false
|
||||
)
|
||||
|
@ -83,7 +82,7 @@ class Middleware(
|
|||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun accountRestore() : AccountStatus {
|
||||
fun accountRestore(): AccountStatus {
|
||||
val request = Rpc.Account.Delete.Request(
|
||||
revert = true
|
||||
)
|
||||
|
@ -796,6 +795,27 @@ class Middleware(
|
|||
if (BuildConfig.DEBUG) logResponse(response)
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun blockLinkSetAppearance(
|
||||
command: Command.SetLinkAppearance,
|
||||
): Payload {
|
||||
val content = command.content
|
||||
val request = Rpc.BlockLink.ListSetAppearance.Request(
|
||||
contextId = command.contextId,
|
||||
blockIds = listOf(command.blockId),
|
||||
iconSize = content.iconSize.toMiddlewareModel(),
|
||||
cardStyle = content.cardStyle.toMiddlewareModel(),
|
||||
description = content.description.toMiddlewareModel(),
|
||||
relations = content.relations.map { it.toMiddlewareModel() }
|
||||
)
|
||||
if (BuildConfig.DEBUG) logRequest(request)
|
||||
val response = service.blockLinkListSetAppearance(
|
||||
request
|
||||
)
|
||||
if (BuildConfig.DEBUG) logResponse(response)
|
||||
return response.event.toPayload()
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun blockUpload(command: Command.UploadBlock): Payload {
|
||||
val request = Rpc.Block.Upload.Request(
|
||||
|
@ -941,7 +961,7 @@ class Middleware(
|
|||
command.type?.let { details[Relations.TYPE] = it }
|
||||
|
||||
val request = Rpc.Object.Create.Request(
|
||||
details = details.toMap()
|
||||
details = details.toMap()
|
||||
)
|
||||
|
||||
if (BuildConfig.DEBUG) logRequest(request)
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.anytypeio.anytype.middleware.interactor
|
|||
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Event
|
||||
import com.anytypeio.anytype.middleware.mappers.toCoreLinkRelationModel
|
||||
import com.anytypeio.anytype.middleware.mappers.toCoreModel
|
||||
import com.anytypeio.anytype.middleware.mappers.toCoreModels
|
||||
import com.anytypeio.anytype.middleware.mappers.toCoreModelsAlign
|
||||
|
@ -112,7 +113,10 @@ fun anytype.Event.Message.toCoreModels(
|
|||
context = context,
|
||||
id = event.id,
|
||||
target = event.targetBlockId?.value_.orEmpty(),
|
||||
fields = event.fields?.value_.toCoreModel()
|
||||
iconSize = event.iconSize?.value_?.toCoreModel(),
|
||||
cardStyle = event.cardStyle?.value_?.toCoreModel(),
|
||||
description = event.description?.value_?.toCoreModel(),
|
||||
relations = event.relations?.value_?.map { it.toCoreLinkRelationModel() }?.toSet()
|
||||
)
|
||||
}
|
||||
blockSetAlign != null -> {
|
||||
|
|
|
@ -13,6 +13,9 @@ typealias MBFile = anytype.model.Block.Content.File
|
|||
typealias MBFileState = anytype.model.Block.Content.File.State
|
||||
typealias MBFileType = anytype.model.Block.Content.File.Type
|
||||
typealias MBLink = anytype.model.Block.Content.Link
|
||||
typealias MBLinkIconSize = anytype.model.Block.Content.Link.IconSize
|
||||
typealias MBLinkCardStyle = anytype.model.Block.Content.Link.CardStyle
|
||||
typealias MBLinkDescription = anytype.model.Block.Content.Link.Description
|
||||
typealias MBLinkStyle = anytype.model.Block.Content.Link.Style
|
||||
typealias MBBookmark = anytype.model.Block.Content.Bookmark
|
||||
typealias MBLayout = anytype.model.Block.Content.Layout
|
||||
|
|
|
@ -182,11 +182,47 @@ fun MBlock.toCoreModelsLink(): Block.Content.Link {
|
|||
val content = checkNotNull(link)
|
||||
return Block.Content.Link(
|
||||
target = content.targetBlockId,
|
||||
fields = Block.Fields(content.fields?.toMap().orEmpty()),
|
||||
type = content.style.toCoreModels()
|
||||
type = content.style.toCoreModels(),
|
||||
iconSize = content.iconSize.toCoreModel(),
|
||||
cardStyle = content.cardStyle.toCoreModel(),
|
||||
description = content.description.toCoreModel(),
|
||||
relations = content.relations.map { it.toCoreLinkRelationModel() }.toSet(),
|
||||
)
|
||||
}
|
||||
|
||||
internal fun String.toCoreLinkRelationModel(): Block.Content.Link.Relation {
|
||||
return when (this) {
|
||||
"cover" -> Block.Content.Link.Relation.COVER
|
||||
"name" -> Block.Content.Link.Relation.NAME
|
||||
"type" -> Block.Content.Link.Relation.TYPE
|
||||
else -> Block.Content.Link.Relation.UNKNOWN(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun MBLinkIconSize.toCoreModel(): Block.Content.Link.IconSize {
|
||||
return when (this) {
|
||||
MBLinkIconSize.SizeNone -> Block.Content.Link.IconSize.NONE
|
||||
MBLinkIconSize.SizeSmall -> Block.Content.Link.IconSize.SMALL
|
||||
MBLinkIconSize.SizeMedium -> Block.Content.Link.IconSize.MEDIUM
|
||||
}
|
||||
}
|
||||
|
||||
fun MBLinkCardStyle.toCoreModel(): Block.Content.Link.CardStyle {
|
||||
return when (this) {
|
||||
MBLinkCardStyle.Text -> Block.Content.Link.CardStyle.TEXT
|
||||
MBLinkCardStyle.Card -> Block.Content.Link.CardStyle.CARD
|
||||
MBLinkCardStyle.Inline -> Block.Content.Link.CardStyle.INLINE
|
||||
}
|
||||
}
|
||||
|
||||
fun MBLinkDescription.toCoreModel(): Block.Content.Link.Description {
|
||||
return when (this) {
|
||||
MBLinkDescription.None -> Block.Content.Link.Description.NONE
|
||||
MBLinkDescription.Added -> Block.Content.Link.Description.ADDED
|
||||
MBLinkDescription.Content -> Block.Content.Link.Description.CONTENT
|
||||
}
|
||||
}
|
||||
|
||||
fun MBlock.toCoreModelsDivider(): Block.Content.Divider {
|
||||
val content = checkNotNull(div)
|
||||
return Block.Content.Divider(
|
||||
|
@ -334,7 +370,7 @@ fun MDVView.toCoreModels(): DVViewer = DVViewer(
|
|||
sorts = sorts.map { it.toCoreModels() },
|
||||
filters = filters.map { it.toCoreModels() },
|
||||
viewerRelations = relations.map { it.toCoreModels() },
|
||||
cardSize = when(cardSize) {
|
||||
cardSize = when (cardSize) {
|
||||
MDVViewCardSize.Small -> DVViewerCardSize.SMALL
|
||||
MDVViewCardSize.Medium -> DVViewerCardSize.MEDIUM
|
||||
MDVViewCardSize.Large -> DVViewerCardSize.LARGE
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
package com.anytypeio.anytype.middleware.mappers
|
||||
|
||||
import anytype.model.Range
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.BlockSplitMode
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.Position
|
||||
import com.anytypeio.anytype.core_models.Relation
|
||||
|
||||
|
||||
// ---------------------- BLOCKS ------------------------
|
||||
|
@ -94,11 +98,49 @@ fun Block.Content.File.toMiddlewareModel(): MBFile = MBFile(
|
|||
type = type.toMiddlewareModel()
|
||||
)
|
||||
|
||||
fun Block.Content.Link.toMiddlewareModel(): MBLink = MBLink(
|
||||
targetBlockId = target,
|
||||
style = type.toMiddlewareModel(),
|
||||
fields = fields.map
|
||||
)
|
||||
internal fun Block.Content.Link.toMiddlewareModel(): MBLink {
|
||||
return MBLink(
|
||||
targetBlockId = target,
|
||||
style = type.toMiddlewareModel(),
|
||||
iconSize = iconSize.toMiddlewareModel(),
|
||||
cardStyle = cardStyle.toMiddlewareModel(),
|
||||
description = description.toMiddlewareModel(),
|
||||
relations = relations.map { it.toMiddlewareModel() }
|
||||
)
|
||||
}
|
||||
|
||||
internal fun Block.Content.Link.Relation.toMiddlewareModel(): String {
|
||||
return when (this) {
|
||||
Block.Content.Link.Relation.COVER -> "cover"
|
||||
Block.Content.Link.Relation.NAME -> "name"
|
||||
Block.Content.Link.Relation.TYPE -> "type"
|
||||
is Block.Content.Link.Relation.UNKNOWN -> this.value
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Block.Content.Link.Description.toMiddlewareModel(): MBLinkDescription {
|
||||
return when (this) {
|
||||
Block.Content.Link.Description.NONE -> MBLinkDescription.None
|
||||
Block.Content.Link.Description.ADDED -> MBLinkDescription.Added
|
||||
Block.Content.Link.Description.CONTENT -> MBLinkDescription.Content
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Block.Content.Link.CardStyle.toMiddlewareModel(): MBLinkCardStyle {
|
||||
return when (this) {
|
||||
Block.Content.Link.CardStyle.TEXT -> MBLinkCardStyle.Text
|
||||
Block.Content.Link.CardStyle.CARD -> MBLinkCardStyle.Card
|
||||
Block.Content.Link.CardStyle.INLINE -> MBLinkCardStyle.Inline
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Block.Content.Link.IconSize.toMiddlewareModel(): MBLinkIconSize {
|
||||
return when (this) {
|
||||
Block.Content.Link.IconSize.NONE -> MBLinkIconSize.SizeNone
|
||||
Block.Content.Link.IconSize.SMALL -> MBLinkIconSize.SizeSmall
|
||||
Block.Content.Link.IconSize.MEDIUM -> MBLinkIconSize.SizeMedium
|
||||
}
|
||||
}
|
||||
|
||||
fun Block.Content.Link.Type.toMiddlewareModel(): MBLinkStyle = when (this) {
|
||||
Block.Content.Link.Type.PAGE -> MBLinkStyle.Page
|
||||
|
@ -255,7 +297,7 @@ fun Block.Content.DataView.Viewer.toMiddlewareModel(): MDVView =
|
|||
coverRelationKey = coverRelationKey.orEmpty(),
|
||||
coverFit = coverFit,
|
||||
hideIcon = hideIcon,
|
||||
cardSize = when(cardSize) {
|
||||
cardSize = when (cardSize) {
|
||||
Block.Content.DataView.Viewer.Size.SMALL -> MDVViewCardSize.Small
|
||||
Block.Content.DataView.Viewer.Size.MEDIUM -> MDVViewCardSize.Medium
|
||||
Block.Content.DataView.Viewer.Size.LARGE -> MDVViewCardSize.Large
|
||||
|
|
|
@ -286,6 +286,13 @@ interface MiddlewareService {
|
|||
|
||||
//endregion
|
||||
|
||||
//region LINK BLOCK commands
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun blockLinkListSetAppearance(request: Rpc.BlockLink.ListSetAppearance.Request): Rpc.BlockLink.ListSetAppearance.Response
|
||||
|
||||
//endregion
|
||||
|
||||
//region DEBUG commands
|
||||
|
||||
@Throws(Exception::class)
|
||||
|
|
|
@ -263,6 +263,21 @@ class MiddlewareServiceImplementation : MiddlewareService {
|
|||
}
|
||||
}
|
||||
|
||||
override fun blockLinkListSetAppearance(
|
||||
request: Rpc.BlockLink.ListSetAppearance.Request
|
||||
): Rpc.BlockLink.ListSetAppearance.Response {
|
||||
val encoded = Service.blockLinkListSetAppearance(
|
||||
Rpc.BlockLink.ListSetAppearance.Request.ADAPTER.encode(request)
|
||||
)
|
||||
val response = Rpc.BlockLink.ListSetAppearance.Response.ADAPTER.decode(encoded)
|
||||
val error = response.error
|
||||
if (error != null && error.code != Rpc.BlockLink.ListSetAppearance.Response.Error.Code.NULL) {
|
||||
throw Exception(error.description)
|
||||
} else {
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
||||
override fun blockListDelete(request: Rpc.Block.ListDelete.Request): Rpc.Block.ListDelete.Response {
|
||||
val encoded = Service.blockListDelete(Rpc.Block.ListDelete.Request.ADAPTER.encode(request))
|
||||
val response = Rpc.Block.ListDelete.Response.ADAPTER.decode(encoded)
|
||||
|
|
|
@ -38,15 +38,6 @@ interface HomeDashboardEventConverter {
|
|||
null
|
||||
}
|
||||
}
|
||||
is Event.Command.LinkGranularChange -> {
|
||||
event.fields?.let { fields ->
|
||||
HomeDashboardStateMachine.Event.OnLinkFieldsChanged(
|
||||
id = event.id,
|
||||
fields = fields,
|
||||
builder = builder
|
||||
)
|
||||
}
|
||||
}
|
||||
is Event.Command.Details.Set -> {
|
||||
HomeDashboardStateMachine.Event.OnDetailsUpdated(
|
||||
context = event.context,
|
||||
|
@ -72,7 +63,7 @@ interface HomeDashboardEventConverter {
|
|||
)
|
||||
}
|
||||
else -> {
|
||||
Timber.d("Ignored event: $event")
|
||||
Timber.v("Ignored event: $event")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,10 @@ import com.anytypeio.anytype.core_models.ext.set
|
|||
import com.anytypeio.anytype.core_models.ext.unset
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.common.StateReducer
|
||||
import com.anytypeio.anytype.presentation.dashboard.HomeDashboardStateMachine.*
|
||||
import com.anytypeio.anytype.presentation.dashboard.HomeDashboardStateMachine.Event
|
||||
import com.anytypeio.anytype.presentation.dashboard.HomeDashboardStateMachine.Interactor
|
||||
import com.anytypeio.anytype.presentation.dashboard.HomeDashboardStateMachine.Reducer
|
||||
import com.anytypeio.anytype.presentation.dashboard.HomeDashboardStateMachine.State
|
||||
import com.anytypeio.anytype.presentation.extension.addAndSortByIds
|
||||
import com.anytypeio.anytype.presentation.extension.sortByIds
|
||||
import com.anytypeio.anytype.presentation.extension.updateDetails
|
||||
|
@ -106,12 +109,6 @@ sealed class HomeDashboardStateMachine {
|
|||
val children: List<String>
|
||||
) : Event()
|
||||
|
||||
data class OnLinkFieldsChanged(
|
||||
val id: String,
|
||||
val fields: Block.Fields,
|
||||
val builder: UrlBuilder
|
||||
) : Event()
|
||||
|
||||
object OnDashboardLoadingStarted : Event()
|
||||
|
||||
object OnStartedCreatingPage : Event()
|
||||
|
@ -191,16 +188,6 @@ sealed class HomeDashboardStateMachine {
|
|||
blocks = state.blocks.addAndSortByIds(state.childrenIdsList, new)
|
||||
)
|
||||
}
|
||||
is Event.OnLinkFieldsChanged -> {
|
||||
state.copy(
|
||||
blocks = state.blocks.updateDetails(
|
||||
event.id,
|
||||
event.fields,
|
||||
event.builder,
|
||||
objectTypes = state.objectTypes
|
||||
)
|
||||
)
|
||||
}
|
||||
is Event.OnDetailsUpdated -> {
|
||||
state.copy(
|
||||
blocks = state.blocks.updateDetails(
|
||||
|
|
|
@ -100,9 +100,16 @@ class DocumentExternalEventReducer : StateReducer<List<Block>, Event> {
|
|||
is Event.Command.LinkGranularChange -> state.replace(
|
||||
replacement = { block ->
|
||||
val content = block.content<Block.Content.Link>()
|
||||
val iconSize = event.iconSize ?: content.iconSize
|
||||
val cardStyle = event.cardStyle ?: content.cardStyle
|
||||
val description = event.description ?: content.description
|
||||
val relations = event.relations ?: content.relations
|
||||
block.copy(
|
||||
content = content.copy(
|
||||
fields = event.fields ?: content.fields
|
||||
iconSize = iconSize,
|
||||
cardStyle = cardStyle,
|
||||
description = description,
|
||||
relations = relations
|
||||
)
|
||||
)
|
||||
},
|
||||
|
@ -138,7 +145,7 @@ class DocumentExternalEventReducer : StateReducer<List<Block>, Event> {
|
|||
typealias Flag = Int
|
||||
|
||||
object Flags {
|
||||
const val FLAG_REFRESH : Flag = 0
|
||||
const val FLAG_REFRESH: Flag = 0
|
||||
val skipRefreshKeys = listOf(
|
||||
Relations.NAME,
|
||||
Relations.LAST_MODIFIED_DATE,
|
||||
|
@ -147,9 +154,9 @@ object Flags {
|
|||
)
|
||||
}
|
||||
|
||||
fun List<Event>.flags(ctx: Id) : List<Flag> {
|
||||
fun List<Event>.flags(ctx: Id): List<Flag> {
|
||||
forEach { event ->
|
||||
when(event) {
|
||||
when (event) {
|
||||
is Event.Command.Details.Amend -> {
|
||||
if (event.target == ctx) {
|
||||
if (event.details.keys.any { key -> !Flags.skipRefreshKeys.contains(key) }) {
|
||||
|
|
|
@ -4,14 +4,13 @@ import com.anytypeio.anytype.core_models.Block
|
|||
import com.anytypeio.anytype.core_models.Document
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.ext.content
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Media.Bookmark.Companion.SEARCH_FIELD_DESCRIPTION_KEY
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Media.Bookmark.Companion.SEARCH_FIELD_TITLE_KEY
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Media.Bookmark.Companion.SEARCH_FIELD_URL_KEY
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Searchable.Field.Companion.DEFAULT_SEARCH_FIELD_KEY
|
||||
import com.anytypeio.anytype.presentation.extension.shift
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.getLinkToObjectAppearanceParams
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.LinkAppearanceFactory
|
||||
import timber.log.Timber
|
||||
|
||||
fun List<BlockView>.singleStylingMode(
|
||||
|
@ -947,16 +946,23 @@ fun List<BlockView>.update(blockView: BlockView) = this.map {
|
|||
if (it.id == blockView.id) blockView else it
|
||||
}
|
||||
|
||||
fun Document.getAppearanceParamsOfBlockLink(blockId: Id, details: Block.Details)
|
||||
: BlockView.Appearance.Params? {
|
||||
fun Document.getLinkAppearanceMenu(
|
||||
blockId: Id,
|
||||
details: Block.Details
|
||||
): BlockView.Appearance.Menu? {
|
||||
val block = this.find { it.id == blockId }
|
||||
val content = block?.content
|
||||
if (block != null && content is Block.Content.Link) {
|
||||
return if (block != null && content is Block.Content.Link) {
|
||||
val target = content.asLink().target
|
||||
val obj = ObjectWrapper.Basic(details.details[target]?.map ?: emptyMap())
|
||||
return block.fields.getLinkToObjectAppearanceParams(layout = obj.layout)
|
||||
val factory = LinkAppearanceFactory(
|
||||
content = content,
|
||||
layout = obj.layout
|
||||
)
|
||||
return factory.createAppearanceMenuItems()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun List<BlockView>.updateTableOfContentsViews(header: BlockView.Text.Header): List<BlockView> {
|
||||
|
@ -1017,6 +1023,6 @@ fun List<BlockView>.fillTableOfContents(): List<BlockView> {
|
|||
}
|
||||
}
|
||||
|
||||
fun BlockView.Text.isStyleClearable() : Boolean {
|
||||
fun BlockView.Text.isStyleClearable(): Boolean {
|
||||
return this.isListBlock || this is BlockView.Text.Highlight
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.anytypeio.anytype.presentation.editor.editor.model
|
||||
|
||||
import com.anytypeio.anytype.core_models.Block.Content.Link.*
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Url
|
||||
import com.anytypeio.anytype.core_utils.ui.ViewType
|
||||
|
@ -170,38 +171,43 @@ sealed class BlockView : ViewType {
|
|||
}
|
||||
|
||||
interface Appearance {
|
||||
data class Params(
|
||||
val canHaveIcon: Boolean,
|
||||
val canHaveCover: Boolean,
|
||||
val canHaveDescription: Boolean,
|
||||
val style: Double,
|
||||
val iconSize: Double,
|
||||
val withIcon: Boolean,
|
||||
val withName: Boolean,
|
||||
val withDescription: Boolean? = null,
|
||||
val withCover: Boolean? = null
|
||||
) {
|
||||
companion object {
|
||||
fun default(): Params = Params(
|
||||
style = LINK_STYLE_TEXT,
|
||||
iconSize = LINK_ICON_SIZE_SMALL,
|
||||
withIcon = true,
|
||||
withName = true,
|
||||
canHaveCover = true,
|
||||
canHaveDescription = true,
|
||||
canHaveIcon = true
|
||||
)
|
||||
|
||||
data class InEditor(
|
||||
val isCard: Boolean,
|
||||
val showIcon: Boolean,
|
||||
val showName: Boolean,
|
||||
val showDescription: Boolean,
|
||||
val showCover: Boolean
|
||||
)
|
||||
|
||||
data class Menu(
|
||||
val preview: MenuItem.PreviewLayout,
|
||||
val icon: MenuItem.Icon?,
|
||||
val cover: MenuItem.Cover?,
|
||||
val description: MenuItem.Description?
|
||||
)
|
||||
|
||||
sealed interface MenuItem {
|
||||
sealed interface Icon : MenuItem {
|
||||
object NONE : Icon
|
||||
object SMALL : Icon
|
||||
object MEDIUM : Icon
|
||||
}
|
||||
|
||||
fun isCard() = style == LINK_STYLE_CARD
|
||||
}
|
||||
sealed interface Description : MenuItem {
|
||||
object WITH : Description
|
||||
object WITHOUT : Description
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val LINK_STYLE_TEXT = 0.0
|
||||
const val LINK_STYLE_CARD = 1.0
|
||||
const val LINK_ICON_SIZE_SMALL = 1.0
|
||||
const val LINK_ICON_SIZE_MEDIUM = 2.0
|
||||
const val LINK_ICON_SIZE_LARGE = 3.0
|
||||
sealed interface Cover : MenuItem {
|
||||
object WITH : Cover
|
||||
object WITHOUT : Cover
|
||||
}
|
||||
|
||||
sealed interface PreviewLayout : MenuItem {
|
||||
object TEXT : PreviewLayout
|
||||
object CARD : PreviewLayout
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -461,9 +467,10 @@ sealed class BlockView : ViewType {
|
|||
) : Text() {
|
||||
override fun getViewType() = HOLDER_TOGGLE
|
||||
override val body: String get() = text
|
||||
val isCreateBlockButtonVisible : Boolean get() {
|
||||
return mode == Mode.EDIT && toggled && isEmpty
|
||||
}
|
||||
val isCreateBlockButtonVisible: Boolean
|
||||
get() {
|
||||
return mode == Mode.EDIT && toggled && isEmpty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -895,7 +902,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() {
|
||||
|
||||
abstract val text: String?
|
||||
abstract val description: String?
|
||||
|
@ -1061,7 +1068,7 @@ sealed class BlockView : ViewType {
|
|||
data class TableOfContentsItem(
|
||||
val id: Id,
|
||||
val name: String,
|
||||
val depth : Int
|
||||
val depth: Int
|
||||
)
|
||||
|
||||
enum class Mode { READ, EDIT }
|
||||
|
|
|
@ -28,11 +28,7 @@ import com.anytypeio.anytype.presentation.mapper.toPictureView
|
|||
import com.anytypeio.anytype.presentation.mapper.toVideoView
|
||||
import com.anytypeio.anytype.presentation.mapper.toView
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.ObjectAppearanceIconState.NONE
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.ObjectAppearancePreviewLayoutState.CARD
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.getLinkToObjectAppearanceParams
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.getObjectAppearanceIconState
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.getObjectAppearancePreviewLayoutState
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.LinkAppearanceFactory
|
||||
import com.anytypeio.anytype.presentation.relations.DocumentRelationView
|
||||
import com.anytypeio.anytype.presentation.relations.view
|
||||
import timber.log.Timber
|
||||
|
@ -458,6 +454,7 @@ class DefaultBlockViewRenderer @Inject constructor(
|
|||
)
|
||||
val link = toLinks(
|
||||
block = block,
|
||||
content = content,
|
||||
indent = indent,
|
||||
obj = obj,
|
||||
mode = mode,
|
||||
|
@ -1260,6 +1257,7 @@ class DefaultBlockViewRenderer @Inject constructor(
|
|||
|
||||
private fun toLinks(
|
||||
block: Block,
|
||||
content: Content.Link,
|
||||
indent: Int,
|
||||
obj: ObjectWrapper.Basic,
|
||||
mode: EditorMode,
|
||||
|
@ -1293,6 +1291,7 @@ class DefaultBlockViewRenderer @Inject constructor(
|
|||
} else {
|
||||
link(
|
||||
block = block,
|
||||
content = content,
|
||||
indent = indent,
|
||||
obj = obj,
|
||||
mode = mode,
|
||||
|
@ -1306,63 +1305,66 @@ class DefaultBlockViewRenderer @Inject constructor(
|
|||
private fun link(
|
||||
mode: Editor.Mode,
|
||||
block: Block,
|
||||
content: Content.Link,
|
||||
indent: Int,
|
||||
obj: ObjectWrapper.Basic,
|
||||
selection: Set<Id>,
|
||||
isPreviousBlockMedia: Boolean
|
||||
): BlockView.LinkToObject.Default {
|
||||
val appearanceParams = block.fields.getLinkToObjectAppearanceParams(obj.layout)
|
||||
val isCard = appearanceParams.getObjectAppearancePreviewLayoutState() == CARD
|
||||
val icon = if (appearanceParams.getObjectAppearanceIconState() == NONE) {
|
||||
ObjectIcon.None
|
||||
} else {
|
||||
val factory = LinkAppearanceFactory(content, obj.layout)
|
||||
val inEditorAppearance = factory.createInEditorLinkAppearance()
|
||||
val isCard = inEditorAppearance.isCard
|
||||
val icon = if (inEditorAppearance.showIcon) {
|
||||
ObjectIcon.from(
|
||||
obj = obj,
|
||||
layout = obj.layout,
|
||||
builder = urlBuilder
|
||||
)
|
||||
}
|
||||
val name = if (!appearanceParams.withName) {
|
||||
null
|
||||
} else {
|
||||
ObjectIcon.None
|
||||
}
|
||||
val name = if (inEditorAppearance.showName) {
|
||||
obj.getProperObjectName()
|
||||
}
|
||||
val description = if (isCard && appearanceParams.withDescription == true) {
|
||||
if (obj.description.isNullOrBlank()) obj.snippet else obj.description
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
var coverColor: CoverColor? = null
|
||||
var coverImage: Url? = null
|
||||
var coverGradient: String? = null
|
||||
|
||||
if (isCard && appearanceParams.canHaveCover && appearanceParams.withCover == true) {
|
||||
when (val type = 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: $type")
|
||||
}
|
||||
}
|
||||
|
||||
return if (isCard) {
|
||||
val description = if (inEditorAppearance.showDescription) {
|
||||
if (obj.description.isNullOrBlank()) obj.snippet else obj.description
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
var coverColor: CoverColor? = null
|
||||
var coverImage: Url? = null
|
||||
var coverGradient: String? = null
|
||||
|
||||
if (inEditorAppearance.showCover) {
|
||||
when (val type = 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: $type")
|
||||
}
|
||||
}
|
||||
|
||||
BlockView.LinkToObject.Default.Card(
|
||||
id = block.id,
|
||||
icon = icon,
|
||||
|
|
|
@ -1,14 +1,21 @@
|
|||
package com.anytypeio.anytype.presentation.mapper
|
||||
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.core_models.ext.textColor
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.DVFilter
|
||||
import com.anytypeio.anytype.core_models.DVFilterCondition
|
||||
import com.anytypeio.anytype.core_models.DVFilterOperator
|
||||
import com.anytypeio.anytype.core_models.DVSort
|
||||
import com.anytypeio.anytype.core_models.DocumentInfo
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
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.ext.textStyle
|
||||
import com.anytypeio.anytype.domain.config.DebugSettings
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.dashboard.DashboardView
|
||||
import com.anytypeio.anytype.presentation.editor.editor.Markup
|
||||
import com.anytypeio.anytype.presentation.editor.editor.ThemeColor
|
||||
import com.anytypeio.anytype.presentation.editor.editor.control.ControlPanelState
|
||||
import com.anytypeio.anytype.presentation.editor.editor.mention.createMentionMarkup
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.Alignment
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
|
@ -20,7 +27,12 @@ import com.anytypeio.anytype.presentation.objects.ObjectTypeView
|
|||
import com.anytypeio.anytype.presentation.objects.getProperName
|
||||
import com.anytypeio.anytype.presentation.relations.type
|
||||
import com.anytypeio.anytype.presentation.sets.buildGridRow
|
||||
import com.anytypeio.anytype.presentation.sets.model.*
|
||||
import com.anytypeio.anytype.presentation.sets.model.ColumnView
|
||||
import com.anytypeio.anytype.presentation.sets.model.FilterExpression
|
||||
import com.anytypeio.anytype.presentation.sets.model.FilterValue
|
||||
import com.anytypeio.anytype.presentation.sets.model.SimpleRelationView
|
||||
import com.anytypeio.anytype.presentation.sets.model.SortingExpression
|
||||
import com.anytypeio.anytype.presentation.sets.model.Viewer
|
||||
import com.anytypeio.anytype.presentation.settings.EditorSettings
|
||||
|
||||
fun Block.Content.File.toPictureView(
|
||||
|
@ -595,11 +607,11 @@ fun List<Map<String, Any?>>.filterRecordsBy(filterBy: String): List<Map<String,
|
|||
filter { it.containsKey(filterBy) }
|
||||
|
||||
fun List<Map<String, Any?>>.toGridRecordRows(
|
||||
columns: List<ColumnView>,
|
||||
relations: List<Relation>,
|
||||
types: List<ObjectType>,
|
||||
details: Map<Id, Block.Fields>,
|
||||
builder: UrlBuilder
|
||||
columns: List<ColumnView>,
|
||||
relations: List<Relation>,
|
||||
types: List<ObjectType>,
|
||||
details: Map<Id, Block.Fields>,
|
||||
builder: UrlBuilder
|
||||
): List<Viewer.GridView.Row> {
|
||||
val rows = mutableListOf<Viewer.GridView.Row>()
|
||||
forEach { record ->
|
||||
|
@ -617,8 +629,8 @@ fun List<Map<String, Any?>>.toGridRecordRows(
|
|||
|
||||
// TODO maybe rename toViewerHeaders
|
||||
fun List<Block.Content.DataView.Viewer.ViewerRelation>.toViewerColumns(
|
||||
relations: List<Relation>,
|
||||
filterBy: List<String>
|
||||
relations: List<Relation>,
|
||||
filterBy: List<String>
|
||||
): List<ColumnView> {
|
||||
val columns = mutableListOf<ColumnView>()
|
||||
this.filter { it.key !in filterBy }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.anytypeio.anytype.presentation.objects
|
||||
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.ObjectAppearanceIconState
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.MenuItem
|
||||
|
||||
|
||||
sealed class ObjectAppearanceSettingView {
|
||||
|
||||
|
@ -9,21 +10,20 @@ sealed class ObjectAppearanceSettingView {
|
|||
}
|
||||
|
||||
sealed class Settings : ObjectAppearanceSettingView() {
|
||||
data class PreviewLayout(val style: Double?) : Settings()
|
||||
data class Icon(val state: ObjectAppearanceIconState) : Settings()
|
||||
data class Cover(val withCover: Boolean?) : Settings()
|
||||
data class PreviewLayout(val previewLayoutState: MenuItem.PreviewLayout) : Settings()
|
||||
data class Icon(val icon: MenuItem.Icon) : Settings()
|
||||
data class Cover(val coverState: MenuItem.Cover) : Settings()
|
||||
}
|
||||
|
||||
sealed class Relation : ObjectAppearanceSettingView() {
|
||||
data class Name(val withName: Boolean?) : Relation()
|
||||
data class Description(val withDescription: Boolean?) : Relation()
|
||||
object Name: Relation()
|
||||
data class Description(val description: MenuItem.Description) : Relation()
|
||||
}
|
||||
|
||||
sealed class Icon : ObjectAppearanceSettingView() {
|
||||
data class None(val isSelected: Boolean) : Icon()
|
||||
data class Small(val isSelected: Boolean) : Icon()
|
||||
data class Medium(val isSelected: Boolean) : Icon()
|
||||
data class Large(val isSelected: Boolean) : Icon()
|
||||
data class None(val isSelected: Boolean) : Icon()
|
||||
}
|
||||
|
||||
sealed class Cover : ObjectAppearanceSettingView() {
|
||||
|
|
|
@ -3,37 +3,37 @@ package com.anytypeio.anytype.presentation.objects
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Block.Content.Link
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.domain.block.interactor.UpdateFields
|
||||
import com.anytypeio.anytype.domain.block.interactor.SetLinkAppearance
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
import com.anytypeio.anytype.presentation.editor.editor.ext.getAppearanceParamsOfBlockLink
|
||||
import com.anytypeio.anytype.presentation.editor.editor.ext.getLinkAppearanceMenu
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.getObjectAppearanceIconState
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectAppearanceSettingView.Relation
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectAppearanceSettingView.Section
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectAppearanceSettingView.Settings
|
||||
import com.anytypeio.anytype.presentation.util.Dispatcher
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
class ObjectAppearanceSettingViewModel(
|
||||
private val storage: Editor.Storage,
|
||||
private val updateFields: UpdateFields,
|
||||
private val setLinkAppearance: SetLinkAppearance,
|
||||
private val dispatcher: Dispatcher<Payload>
|
||||
) : ViewModel() {
|
||||
|
||||
val objectPreviewState = MutableSharedFlow<State>(replay = 0)
|
||||
val commands = MutableSharedFlow<Command>(replay = 0)
|
||||
private val paramsAppearance = MutableSharedFlow<BlockView.Appearance.Params?>()
|
||||
private val paramsAppearance = MutableSharedFlow<BlockView.Appearance.Menu>()
|
||||
private val jobs = mutableListOf<Job>()
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
paramsAppearance
|
||||
.filterNotNull()
|
||||
.collectLatest { onNewParams(it) }
|
||||
}
|
||||
}
|
||||
|
@ -41,50 +41,51 @@ class ObjectAppearanceSettingViewModel(
|
|||
fun onStart(blockId: Id) {
|
||||
jobs += viewModelScope.launch {
|
||||
storage.document.observe().collectLatest { state ->
|
||||
val params = state.getAppearanceParamsOfBlockLink(
|
||||
val menu = state.getLinkAppearanceMenu(
|
||||
blockId = blockId,
|
||||
details = storage.details.current()
|
||||
)
|
||||
paramsAppearance.emit(params)
|
||||
if (menu != null) {
|
||||
paramsAppearance.emit(menu)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onNewParams(params: BlockView.Appearance.Params) {
|
||||
private fun onNewParams(menu: BlockView.Appearance.Menu) {
|
||||
viewModelScope.launch {
|
||||
val views = initSettingsMenu(params)
|
||||
val views = initSettingsMenu(menu)
|
||||
objectPreviewState.emit(State.Success(views))
|
||||
}
|
||||
}
|
||||
|
||||
private fun initSettingsMenu(params: BlockView.Appearance.Params): List<ObjectAppearanceSettingView> {
|
||||
val menus = mutableListOf<ObjectAppearanceSettingView>()
|
||||
menus.add(ObjectAppearanceSettingView.Settings.PreviewLayout(params.style))
|
||||
if (params.canHaveIcon) {
|
||||
val iconState = params.getObjectAppearanceIconState()
|
||||
menus.add(ObjectAppearanceSettingView.Settings.Icon(iconState))
|
||||
private fun initSettingsMenu(menu: BlockView.Appearance.Menu): List<ObjectAppearanceSettingView> {
|
||||
return buildList {
|
||||
add(Settings.PreviewLayout(menu.preview))
|
||||
if (menu.icon != null) {
|
||||
add(Settings.Icon(menu.icon))
|
||||
}
|
||||
if (menu.cover != null) {
|
||||
add(Settings.Cover(menu.cover))
|
||||
}
|
||||
add(Section.FeaturedRelations)
|
||||
add(Relation.Name)
|
||||
if (menu.description != null) {
|
||||
add(Relation.Description(menu.description))
|
||||
}
|
||||
}
|
||||
if (params.canHaveCover) {
|
||||
menus.add(ObjectAppearanceSettingView.Settings.Cover(params.withCover))
|
||||
}
|
||||
menus.add(ObjectAppearanceSettingView.Section.FeaturedRelations)
|
||||
menus.add(ObjectAppearanceSettingView.Relation.Name(params.withName))
|
||||
if (params.canHaveDescription) {
|
||||
menus.add(ObjectAppearanceSettingView.Relation.Description(params.withDescription))
|
||||
}
|
||||
return menus
|
||||
}
|
||||
|
||||
fun onItemClicked(item: ObjectAppearanceSettingView) {
|
||||
viewModelScope.launch {
|
||||
when (item) {
|
||||
is ObjectAppearanceSettingView.Settings.Cover -> {
|
||||
is Settings.Cover -> {
|
||||
commands.emit(Command.CoverScreen)
|
||||
}
|
||||
is ObjectAppearanceSettingView.Settings.Icon -> {
|
||||
is Settings.Icon -> {
|
||||
commands.emit(Command.IconScreen)
|
||||
}
|
||||
is ObjectAppearanceSettingView.Settings.PreviewLayout -> {
|
||||
is Settings.PreviewLayout -> {
|
||||
commands.emit(Command.PreviewLayoutScreen)
|
||||
}
|
||||
else -> {}
|
||||
|
@ -93,48 +94,37 @@ class ObjectAppearanceSettingViewModel(
|
|||
}
|
||||
|
||||
fun onToggleClicked(
|
||||
item: ObjectAppearanceSettingView,
|
||||
description: Relation.Description,
|
||||
ctx: Id,
|
||||
blockId: Id,
|
||||
isChecked: Boolean
|
||||
) {
|
||||
val block = storage.document.get().firstOrNull { it.id == blockId }
|
||||
if (block != null) {
|
||||
when (item) {
|
||||
is ObjectAppearanceSettingView.Relation.Description -> {
|
||||
if (isChecked != block.fields.withDescription) {
|
||||
val fields = block.fields.copy(
|
||||
map = block.fields.map.toMutableMap().apply {
|
||||
put(Block.Fields.WITH_DESCRIPTION_KEY, isChecked)
|
||||
}
|
||||
)
|
||||
proceedWithFieldsUpdate(ctx, blockId, fields)
|
||||
val content = block?.content
|
||||
if (block != null && content is Link) {
|
||||
if (isChecked != content.hasDescription) {
|
||||
val newContent = content.copy(
|
||||
description = if (isChecked) {
|
||||
Link.Description.ADDED
|
||||
} else {
|
||||
Link.Description.NONE
|
||||
}
|
||||
}
|
||||
is ObjectAppearanceSettingView.Relation.Name -> {
|
||||
if (isChecked != block.fields.withName) {
|
||||
val fields = block.fields.copy(
|
||||
map = block.fields.map.toMutableMap().apply {
|
||||
put(Block.Fields.WITH_NAME_KEY, isChecked)
|
||||
}
|
||||
)
|
||||
proceedWithFieldsUpdate(ctx, blockId, fields)
|
||||
}
|
||||
}
|
||||
else -> throw UnsupportedOperationException("Wrong item type:$item")
|
||||
)
|
||||
setLinkAppearance(ctx, blockId, newContent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithFieldsUpdate(ctx: Id, blockId: Id, fields: Block.Fields) {
|
||||
private fun setLinkAppearance(ctx: Id, blockId: Id, content: Link) {
|
||||
viewModelScope.launch {
|
||||
updateFields.invoke(
|
||||
UpdateFields.Params(
|
||||
context = ctx,
|
||||
fields = listOf(Pair(blockId, fields))
|
||||
setLinkAppearance(
|
||||
SetLinkAppearance.Params(
|
||||
contextId = ctx,
|
||||
blockId = blockId,
|
||||
content = content
|
||||
)
|
||||
).proceed(
|
||||
failure = { Timber.e(it, "Error while updating icon size for object") },
|
||||
failure = { Timber.e(it, "Error while set link appearance") },
|
||||
success = { dispatcher.send(it) }
|
||||
)
|
||||
}
|
||||
|
@ -156,13 +146,13 @@ class ObjectAppearanceSettingViewModel(
|
|||
//region FACTORY
|
||||
class Factory(
|
||||
private val storage: Editor.Storage,
|
||||
private val updateFields: UpdateFields,
|
||||
private val setLinkAppearance: SetLinkAppearance,
|
||||
private val dispatcher: Dispatcher<Payload>
|
||||
) : ViewModelProvider.Factory {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return ObjectAppearanceSettingViewModel(storage, updateFields, dispatcher) as T
|
||||
return ObjectAppearanceSettingViewModel(storage, setLinkAppearance, dispatcher) as T
|
||||
}
|
||||
}
|
||||
//endregion
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package com.anytypeio.anytype.presentation.objects.appearance
|
||||
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Block.Content.Link.CardStyle
|
||||
import com.anytypeio.anytype.core_models.Block.Content.Link.IconSize
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.MenuItem
|
||||
|
||||
internal class LinkAppearanceFactory(
|
||||
private val content: Block.Content.Link,
|
||||
layout: ObjectType.Layout?
|
||||
) {
|
||||
|
||||
private val isTodoLayout = layout == ObjectType.Layout.TODO
|
||||
private val isNoteLayout = layout == ObjectType.Layout.NOTE
|
||||
private val withDescription = content.cardStyle != CardStyle.TEXT && !isNoteLayout
|
||||
|
||||
//todo Cover menu option is off. No proper design yet.
|
||||
private val canHaveCover: Boolean =
|
||||
false && !isNoteLayout && content.cardStyle != CardStyle.TEXT
|
||||
|
||||
private val withCover = canHaveCover && (content.hasCover)
|
||||
|
||||
internal fun createInEditorLinkAppearance(): BlockView.Appearance.InEditor {
|
||||
val withIcon = when {
|
||||
isNoteLayout -> false
|
||||
isTodoLayout -> true
|
||||
else -> content.iconSize != IconSize.NONE
|
||||
}
|
||||
return BlockView.Appearance.InEditor(
|
||||
showIcon = withIcon,
|
||||
isCard = content.cardStyle == CardStyle.CARD,
|
||||
showName = true,
|
||||
showDescription = withDescription && content.hasDescription,
|
||||
showCover = withCover
|
||||
)
|
||||
}
|
||||
|
||||
internal fun createAppearanceMenuItems(): BlockView.Appearance.Menu {
|
||||
val hasIconMenuItem = !isTodoLayout && !isNoteLayout
|
||||
val preview = when (content.cardStyle) {
|
||||
CardStyle.TEXT -> MenuItem.PreviewLayout.TEXT
|
||||
CardStyle.CARD,
|
||||
CardStyle.INLINE -> MenuItem.PreviewLayout.CARD
|
||||
}
|
||||
val icon = if (hasIconMenuItem) {
|
||||
when (content.iconSize) {
|
||||
IconSize.NONE -> MenuItem.Icon.NONE
|
||||
IconSize.SMALL -> MenuItem.Icon.SMALL
|
||||
IconSize.MEDIUM -> MenuItem.Icon.MEDIUM
|
||||
}
|
||||
} else null
|
||||
val cover = if (canHaveCover) {
|
||||
when (withCover) {
|
||||
true -> MenuItem.Cover.WITH
|
||||
false -> MenuItem.Cover.WITHOUT
|
||||
}
|
||||
|
||||
} else null
|
||||
val description = if (withDescription) {
|
||||
when (content.description) {
|
||||
Block.Content.Link.Description.NONE -> MenuItem.Description.WITHOUT
|
||||
Block.Content.Link.Description.ADDED,
|
||||
Block.Content.Link.Description.CONTENT -> MenuItem.Description.WITH
|
||||
}
|
||||
} else null
|
||||
return BlockView.Appearance.Menu(
|
||||
preview = preview,
|
||||
icon = icon,
|
||||
cover = cover,
|
||||
description = description
|
||||
)
|
||||
}
|
||||
}
|
|
@ -3,12 +3,13 @@ package com.anytypeio.anytype.presentation.objects.appearance
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Block.Content.Link
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.domain.block.interactor.UpdateFields
|
||||
import com.anytypeio.anytype.domain.block.interactor.SetLinkAppearance
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
import com.anytypeio.anytype.presentation.editor.editor.ext.getAppearanceParamsOfBlockLink
|
||||
import com.anytypeio.anytype.presentation.editor.editor.ext.getLinkAppearanceMenu
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.MenuItem
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectAppearanceSettingView
|
||||
import com.anytypeio.anytype.presentation.util.Dispatcher
|
||||
import kotlinx.coroutines.Job
|
||||
|
@ -18,7 +19,7 @@ import timber.log.Timber
|
|||
|
||||
class ObjectAppearanceCoverViewModel(
|
||||
private val storage: Editor.Storage,
|
||||
private val updateFields: UpdateFields,
|
||||
private val setLinkAppearance: SetLinkAppearance,
|
||||
private val dispatcher: Dispatcher<Payload>
|
||||
) : ViewModel() {
|
||||
|
||||
|
@ -27,20 +28,20 @@ class ObjectAppearanceCoverViewModel(
|
|||
|
||||
fun onStart(blockId: Id) {
|
||||
jobs += viewModelScope.launch {
|
||||
val params = storage.document.get().getAppearanceParamsOfBlockLink(
|
||||
val menu = storage.document.get().getLinkAppearanceMenu(
|
||||
blockId = blockId,
|
||||
details = storage.details.current()
|
||||
)
|
||||
if (params != null) {
|
||||
val coverState = params.getObjectAppearanceCoverState()
|
||||
if (menu != null) {
|
||||
val coverState = menu.cover
|
||||
state.emit(
|
||||
State.Success(
|
||||
items = listOf(
|
||||
ObjectAppearanceSettingView.Cover.None(
|
||||
isSelected = coverState == ObjectAppearanceCoverState.NONE
|
||||
isSelected = coverState == MenuItem.Cover.WITHOUT
|
||||
),
|
||||
ObjectAppearanceSettingView.Cover.Visible(
|
||||
isSelected = coverState == ObjectAppearanceCoverState.VISIBLE
|
||||
isSelected = coverState == MenuItem.Cover.WITH
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -52,34 +53,34 @@ class ObjectAppearanceCoverViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
fun onItemClicked(item: ObjectAppearanceSettingView, ctx: Id, blockId: Id) {
|
||||
fun onItemClicked(item: ObjectAppearanceSettingView.Cover, ctx: Id, blockId: Id) {
|
||||
val block = storage.document.get().firstOrNull { it.id == blockId }
|
||||
if (block != null) {
|
||||
val fields = when (item) {
|
||||
is ObjectAppearanceSettingView.Cover.None ->
|
||||
block.fields.copy(
|
||||
map = block.fields.map.toMutableMap().apply {
|
||||
put(Block.Fields.COVER_WITH_KEY, false)
|
||||
}
|
||||
val content = block?.content
|
||||
if (block != null && content is Link) {
|
||||
val relations = content.relations
|
||||
val newContent: Link = when (item) {
|
||||
is ObjectAppearanceSettingView.Cover.None -> {
|
||||
content.copy(
|
||||
relations = relations - Link.Relation.COVER
|
||||
)
|
||||
is ObjectAppearanceSettingView.Cover.Visible ->
|
||||
block.fields.copy(
|
||||
map = block.fields.map.toMutableMap().apply {
|
||||
put(Block.Fields.COVER_WITH_KEY, true)
|
||||
}
|
||||
}
|
||||
is ObjectAppearanceSettingView.Cover.Visible -> {
|
||||
content.copy(
|
||||
relations = relations + Link.Relation.COVER
|
||||
)
|
||||
else -> throw UnsupportedOperationException("Wrong item type:$item")
|
||||
}
|
||||
}
|
||||
proceedWithFieldsUpdate(ctx, blockId, fields)
|
||||
proceedWithFieldsUpdate(ctx, blockId, newContent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithFieldsUpdate(ctx: Id, blockId: Id, fields: Block.Fields) {
|
||||
private fun proceedWithFieldsUpdate(ctx: Id, blockId: Id, content: Link) {
|
||||
viewModelScope.launch {
|
||||
updateFields.invoke(
|
||||
UpdateFields.Params(
|
||||
context = ctx,
|
||||
fields = listOf(Pair(blockId, fields))
|
||||
setLinkAppearance(
|
||||
SetLinkAppearance.Params(
|
||||
contextId = ctx,
|
||||
blockId = blockId,
|
||||
content = content
|
||||
)
|
||||
).proceed(
|
||||
failure = { Timber.e(it, "Error while updating cover visibility for block") },
|
||||
|
@ -97,12 +98,12 @@ class ObjectAppearanceCoverViewModel(
|
|||
|
||||
class Factory(
|
||||
private val storage: Editor.Storage,
|
||||
private val updateFields: UpdateFields,
|
||||
private val setLinkAppearance: SetLinkAppearance,
|
||||
private val dispatcher: Dispatcher<Payload>
|
||||
) : ViewModelProvider.Factory {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return ObjectAppearanceCoverViewModel(storage, updateFields, dispatcher) as T
|
||||
return ObjectAppearanceCoverViewModel(storage, setLinkAppearance, dispatcher) as T
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
package com.anytypeio.anytype.presentation.objects.appearance
|
||||
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.Companion.LINK_ICON_SIZE_LARGE
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.Companion.LINK_ICON_SIZE_MEDIUM
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.Companion.LINK_ICON_SIZE_SMALL
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.Companion.LINK_STYLE_CARD
|
||||
|
||||
enum class ObjectAppearanceIconState { NONE, SMALL, MEDIUM, LARGE, UNKNOWN }
|
||||
enum class ObjectAppearanceCoverState { NONE, VISIBLE }
|
||||
enum class ObjectAppearancePreviewLayoutState { TEXT, CARD }
|
||||
|
||||
fun BlockView.Appearance.Params.getObjectAppearanceIconState(): ObjectAppearanceIconState {
|
||||
return when {
|
||||
!withIcon -> ObjectAppearanceIconState.NONE
|
||||
iconSize == LINK_ICON_SIZE_SMALL -> ObjectAppearanceIconState.SMALL
|
||||
iconSize == LINK_ICON_SIZE_MEDIUM -> ObjectAppearanceIconState.MEDIUM
|
||||
iconSize == LINK_ICON_SIZE_LARGE -> ObjectAppearanceIconState.LARGE
|
||||
else -> ObjectAppearanceIconState.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
fun BlockView.Appearance.Params.getObjectAppearanceCoverState(): ObjectAppearanceCoverState {
|
||||
return if (withCover == true) {
|
||||
ObjectAppearanceCoverState.VISIBLE
|
||||
} else {
|
||||
ObjectAppearanceCoverState.NONE
|
||||
}
|
||||
}
|
||||
|
||||
fun BlockView.Appearance.Params.getObjectAppearancePreviewLayoutState(): ObjectAppearancePreviewLayoutState {
|
||||
return if (style == LINK_STYLE_CARD) {
|
||||
ObjectAppearancePreviewLayoutState.CARD
|
||||
} else {
|
||||
ObjectAppearancePreviewLayoutState.TEXT
|
||||
}
|
||||
}
|
||||
|
||||
fun Block.Fields.getLinkToObjectAppearanceParams(layout: ObjectType.Layout?): BlockView.Appearance.Params {
|
||||
|
||||
var canHaveIcon = true
|
||||
//todo Cover menu option is off. No proper design yet.
|
||||
var canHaveCover = false
|
||||
var canHaveDescription = true
|
||||
|
||||
var iconSize = this.iconSize ?: LINK_ICON_SIZE_MEDIUM
|
||||
val style = this.style ?: BlockView.Appearance.LINK_STYLE_TEXT
|
||||
var withIcon = this.withIcon ?: true
|
||||
val withName = this.withName ?: true
|
||||
var withCover = this.withCover
|
||||
var withDescription = this.withDescription
|
||||
|
||||
if (this.style == BlockView.Appearance.LINK_STYLE_TEXT) {
|
||||
//canHaveCover = false
|
||||
canHaveDescription = false
|
||||
}
|
||||
|
||||
if (layout == ObjectType.Layout.TODO) {
|
||||
canHaveIcon = false
|
||||
withIcon = true
|
||||
iconSize = LINK_ICON_SIZE_MEDIUM
|
||||
}
|
||||
|
||||
if (layout == ObjectType.Layout.NOTE) {
|
||||
canHaveIcon = false
|
||||
//canHaveCover = false
|
||||
canHaveDescription = false
|
||||
withIcon = false
|
||||
withCover = false
|
||||
withDescription = false
|
||||
iconSize = LINK_ICON_SIZE_MEDIUM
|
||||
}
|
||||
|
||||
return BlockView.Appearance.Params(
|
||||
canHaveIcon = canHaveIcon,
|
||||
canHaveCover = canHaveCover,
|
||||
canHaveDescription = canHaveDescription,
|
||||
iconSize = iconSize,
|
||||
style = style,
|
||||
withIcon = withIcon,
|
||||
withName = withName,
|
||||
withCover = withCover,
|
||||
withDescription = withDescription
|
||||
)
|
||||
}
|
|
@ -4,19 +4,13 @@ import androidx.lifecycle.ViewModel
|
|||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Block.Fields.Companion.ICON_SIZE_KEY
|
||||
import com.anytypeio.anytype.core_models.Block.Fields.Companion.ICON_WITH_KEY
|
||||
import com.anytypeio.anytype.core_models.Block.Fields.Companion.WITH_DESCRIPTION_KEY
|
||||
import com.anytypeio.anytype.core_models.Block.Fields.Companion.WITH_NAME_KEY
|
||||
import com.anytypeio.anytype.core_models.Block.Content.Link.IconSize
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.domain.block.interactor.UpdateFields
|
||||
import com.anytypeio.anytype.domain.block.interactor.SetLinkAppearance
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
import com.anytypeio.anytype.presentation.editor.editor.ext.getAppearanceParamsOfBlockLink
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.Companion.LINK_ICON_SIZE_LARGE
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.Companion.LINK_ICON_SIZE_MEDIUM
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.Companion.LINK_ICON_SIZE_SMALL
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectAppearanceSettingView
|
||||
import com.anytypeio.anytype.presentation.editor.editor.ext.getLinkAppearanceMenu
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.MenuItem
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectAppearanceSettingView.Icon
|
||||
import com.anytypeio.anytype.presentation.util.Dispatcher
|
||||
import kotlinx.coroutines.Job
|
||||
|
@ -26,7 +20,7 @@ import timber.log.Timber
|
|||
|
||||
class ObjectAppearanceIconViewModel(
|
||||
private val storage: Editor.Storage,
|
||||
private val updateFields: UpdateFields,
|
||||
private val setLinkAppearance: SetLinkAppearance,
|
||||
private val dispatcher: Dispatcher<Payload>
|
||||
) : ViewModel() {
|
||||
|
||||
|
@ -35,21 +29,18 @@ class ObjectAppearanceIconViewModel(
|
|||
|
||||
fun onStart(blockId: Id) {
|
||||
jobs += viewModelScope.launch {
|
||||
val params = storage.document.get().getAppearanceParamsOfBlockLink(
|
||||
val menu = storage.document.get().getLinkAppearanceMenu(
|
||||
blockId = blockId,
|
||||
details = storage.details.current()
|
||||
)
|
||||
if (params != null) {
|
||||
val iconState = params.getObjectAppearanceIconState()
|
||||
if (menu != null) {
|
||||
val iconState = menu.icon
|
||||
state.emit(
|
||||
State.Success(
|
||||
items = listOf(
|
||||
Icon.None(isSelected = iconState == ObjectAppearanceIconState.NONE),
|
||||
// TODO small icons will be handled later
|
||||
//Icon.Small(isSelected = iconState == ObjectAppearanceIconState.SMALL),
|
||||
Icon.Medium(isSelected = iconState == ObjectAppearanceIconState.MEDIUM)
|
||||
// TODO large icons will be handled later
|
||||
//Icon.Large(isSelected = iconState == ObjectAppearanceIconState.LARGE)
|
||||
Icon.None(isSelected = iconState == MenuItem.Icon.NONE),
|
||||
Icon.Small(isSelected = iconState == MenuItem.Icon.SMALL),
|
||||
Icon.Medium(isSelected = iconState == MenuItem.Icon.MEDIUM)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -64,52 +55,37 @@ class ObjectAppearanceIconViewModel(
|
|||
jobs.forEach { it.cancel() }
|
||||
}
|
||||
|
||||
fun onItemClicked(item: ObjectAppearanceSettingView, ctx: Id, blockId: Id) {
|
||||
fun onItemClicked(item: Icon, ctx: Id, blockId: Id) {
|
||||
val block = storage.document.get().firstOrNull { it.id == blockId }
|
||||
if (block != null) {
|
||||
val fields = when (item) {
|
||||
is Icon.Large ->
|
||||
block.fields.copy(
|
||||
map = block.fields.map.toMutableMap().apply {
|
||||
put(ICON_SIZE_KEY, LINK_ICON_SIZE_LARGE)
|
||||
put(ICON_WITH_KEY, true)
|
||||
}
|
||||
)
|
||||
is Icon.Medium ->
|
||||
block.fields.copy(
|
||||
map = block.fields.map.toMutableMap().apply {
|
||||
put(ICON_SIZE_KEY, LINK_ICON_SIZE_MEDIUM)
|
||||
put(ICON_WITH_KEY, true)
|
||||
}
|
||||
)
|
||||
val content = block?.content
|
||||
if (block != null && content is Block.Content.Link) {
|
||||
val newContent = when (item) {
|
||||
is Icon.Medium -> content.copy(
|
||||
iconSize = IconSize.MEDIUM
|
||||
)
|
||||
is Icon.Small ->
|
||||
block.fields.copy(
|
||||
map = block.fields.map.toMutableMap().apply {
|
||||
put(ICON_SIZE_KEY, LINK_ICON_SIZE_SMALL)
|
||||
put(ICON_WITH_KEY, true)
|
||||
}
|
||||
content.copy(
|
||||
iconSize = IconSize.SMALL
|
||||
)
|
||||
is Icon.None ->
|
||||
block.fields.copy(
|
||||
map = block.fields.map.toMutableMap().apply {
|
||||
put(ICON_WITH_KEY, false)
|
||||
}
|
||||
content.copy(
|
||||
iconSize = IconSize.NONE
|
||||
)
|
||||
else -> throw UnsupportedOperationException("Wrong item type:$item")
|
||||
}
|
||||
proceedWithFieldsUpdate(ctx, blockId, fields)
|
||||
proceedWithFieldsUpdate(ctx, blockId, newContent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithFieldsUpdate(ctx: Id, blockId: Id, fields: Block.Fields) {
|
||||
private fun proceedWithFieldsUpdate(ctx: Id, blockId: Id, content: Block.Content.Link) {
|
||||
viewModelScope.launch {
|
||||
updateFields.invoke(
|
||||
UpdateFields.Params(
|
||||
context = ctx,
|
||||
fields = listOf(Pair(blockId, fields))
|
||||
setLinkAppearance(
|
||||
SetLinkAppearance.Params(
|
||||
contextId = ctx,
|
||||
blockId = blockId,
|
||||
content = content
|
||||
)
|
||||
).proceed(
|
||||
failure = { Timber.e(it, "Error while updating icon size for object") },
|
||||
failure = { Timber.e(it, "Error while updating icon link appearance") },
|
||||
success = {
|
||||
dispatcher.send(it)
|
||||
state.emit(State.Dismiss)
|
||||
|
@ -120,12 +96,12 @@ class ObjectAppearanceIconViewModel(
|
|||
|
||||
class Factory(
|
||||
private val storage: Editor.Storage,
|
||||
private val updateFields: UpdateFields,
|
||||
private val setLinkAppearance: SetLinkAppearance,
|
||||
private val dispatcher: Dispatcher<Payload>
|
||||
) : ViewModelProvider.Factory {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return ObjectAppearanceIconViewModel(storage, updateFields, dispatcher) as T
|
||||
return ObjectAppearanceIconViewModel(storage, setLinkAppearance, dispatcher) as T
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@ import androidx.lifecycle.ViewModel
|
|||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Block.Fields.Companion.STYLE_KEY
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.domain.block.interactor.UpdateFields
|
||||
import com.anytypeio.anytype.domain.block.interactor.SetLinkAppearance
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
import com.anytypeio.anytype.presentation.editor.editor.ext.getAppearanceParamsOfBlockLink
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.Companion.LINK_STYLE_CARD
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.Companion.LINK_STYLE_TEXT
|
||||
import com.anytypeio.anytype.presentation.editor.editor.ext.getLinkAppearanceMenu
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.MenuItem.PreviewLayout
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectAppearanceSettingView
|
||||
import com.anytypeio.anytype.presentation.util.Dispatcher
|
||||
import kotlinx.coroutines.Job
|
||||
|
@ -21,7 +19,7 @@ import timber.log.Timber
|
|||
|
||||
class ObjectAppearancePreviewLayoutViewModel(
|
||||
private val storage: Editor.Storage,
|
||||
private val updateFields: UpdateFields,
|
||||
private val setLinkAppearance: SetLinkAppearance,
|
||||
private val dispatcher: Dispatcher<Payload>
|
||||
) : ViewModel() {
|
||||
|
||||
|
@ -30,20 +28,20 @@ class ObjectAppearancePreviewLayoutViewModel(
|
|||
|
||||
fun onStart(blockId: Id) {
|
||||
jobs += viewModelScope.launch {
|
||||
val params = storage.document.get().getAppearanceParamsOfBlockLink(
|
||||
val menu = storage.document.get().getLinkAppearanceMenu(
|
||||
blockId = blockId,
|
||||
details = storage.details.current()
|
||||
)
|
||||
if (params != null) {
|
||||
val previewLayout = params.getObjectAppearancePreviewLayoutState()
|
||||
if (menu != null) {
|
||||
val previewLayout = menu.preview
|
||||
state.emit(
|
||||
State.Success(
|
||||
items = listOf(
|
||||
ObjectAppearanceSettingView.PreviewLayout.Text(
|
||||
isSelected = previewLayout == ObjectAppearancePreviewLayoutState.TEXT
|
||||
isSelected = previewLayout == PreviewLayout.TEXT
|
||||
),
|
||||
ObjectAppearanceSettingView.PreviewLayout.Card(
|
||||
isSelected = previewLayout == ObjectAppearancePreviewLayoutState.CARD
|
||||
isSelected = previewLayout == PreviewLayout.CARD
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -55,37 +53,40 @@ class ObjectAppearancePreviewLayoutViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
fun onItemClicked(item: ObjectAppearanceSettingView, ctx: Id, blockId: Id) {
|
||||
fun onItemClicked(
|
||||
item: ObjectAppearanceSettingView.PreviewLayout,
|
||||
ctx: Id,
|
||||
blockId: Id
|
||||
) {
|
||||
val block = storage.document.get().find { it.id == blockId }
|
||||
if (block != null) {
|
||||
val fields = when (item) {
|
||||
val content = block?.content
|
||||
if (block != null && content is Block.Content.Link) {
|
||||
val newContent = when (item) {
|
||||
is ObjectAppearanceSettingView.PreviewLayout.Text ->
|
||||
block.fields.copy(
|
||||
map = block.fields.map.toMutableMap().apply {
|
||||
put(STYLE_KEY, LINK_STYLE_TEXT)
|
||||
}
|
||||
content.copy(
|
||||
cardStyle = Block.Content.Link.CardStyle.TEXT
|
||||
)
|
||||
is ObjectAppearanceSettingView.PreviewLayout.Card ->
|
||||
block.fields.copy(
|
||||
map = block.fields.map.toMutableMap().apply {
|
||||
put(STYLE_KEY, LINK_STYLE_CARD)
|
||||
}
|
||||
content.copy(
|
||||
cardStyle = Block.Content.Link.CardStyle.CARD
|
||||
)
|
||||
else -> throw UnsupportedOperationException("Wrong item type:$item")
|
||||
}
|
||||
proceedWithFieldsUpdate(ctx, blockId, fields)
|
||||
proceedWithFieldsUpdate(ctx, blockId, newContent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithFieldsUpdate(ctx: Id, blockId: Id, fields: Block.Fields) {
|
||||
private fun proceedWithFieldsUpdate(ctx: Id, blockId: Id, content: Block.Content.Link) {
|
||||
viewModelScope.launch {
|
||||
updateFields.invoke(
|
||||
UpdateFields.Params(
|
||||
context = ctx,
|
||||
fields = listOf(Pair(blockId, fields))
|
||||
setLinkAppearance(
|
||||
SetLinkAppearance.Params(
|
||||
contextId = ctx,
|
||||
blockId = blockId,
|
||||
content = content
|
||||
)
|
||||
).proceed(
|
||||
failure = { Timber.e(it, "Error while updating preview layout visibility for block") },
|
||||
failure = {
|
||||
Timber.e(it, "Error while updating preview layout visibility for block")
|
||||
},
|
||||
success = {
|
||||
dispatcher.send(it)
|
||||
state.emit(State.Dismiss)
|
||||
|
@ -100,12 +101,16 @@ class ObjectAppearancePreviewLayoutViewModel(
|
|||
|
||||
class Factory(
|
||||
private val storage: Editor.Storage,
|
||||
private val updateFields: UpdateFields,
|
||||
private val setLinkAppearance: SetLinkAppearance,
|
||||
private val dispatcher: Dispatcher<Payload>
|
||||
) : ViewModelProvider.Factory {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return ObjectAppearancePreviewLayoutViewModel(storage, updateFields, dispatcher) as T
|
||||
return ObjectAppearancePreviewLayoutViewModel(
|
||||
storage,
|
||||
setLinkAppearance,
|
||||
dispatcher
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package com.anytypeio.anytype.presentation
|
||||
|
||||
import com.anytypeio.anytype.core_models.Block.Content.Link
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
|
||||
object MockBlockContentFactory {
|
||||
|
||||
fun StubLinkContent(
|
||||
target: String = MockDataFactory.randomUuid(),
|
||||
type: Link.Type = Link.Type.PAGE,
|
||||
iconSize: Link.IconSize = Link.IconSize.SMALL,
|
||||
cardStyle: Link.CardStyle = Link.CardStyle.TEXT,
|
||||
description: Link.Description = Link.Description.NONE,
|
||||
relations: Set<Link.Relation> = emptySet(),
|
||||
): Link = Link(
|
||||
target = target,
|
||||
type = type,
|
||||
iconSize = iconSize,
|
||||
cardStyle = cardStyle,
|
||||
description = description,
|
||||
relations = relations
|
||||
)
|
||||
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
package com.anytypeio.anytype.presentation
|
||||
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Block.Content.Link
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.SmartBlockType
|
||||
import com.anytypeio.anytype.presentation.MockBlockContentFactory.StubLinkContent
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
|
||||
object MockBlockFactory {
|
||||
|
@ -18,7 +20,7 @@ object MockBlockFactory {
|
|||
|
||||
fun paragraph(
|
||||
children: List<Id> = emptyList()
|
||||
) : Block = Block(
|
||||
): Block = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = children,
|
||||
|
@ -197,6 +199,20 @@ object MockBlockFactory {
|
|||
)
|
||||
)
|
||||
|
||||
fun link(
|
||||
id: String = MockDataFactory.randomUuid(),
|
||||
fields: Block.Fields = Block.Fields(emptyMap()),
|
||||
content: Link = StubLinkContent(),
|
||||
children: List<Id> = emptyList(),
|
||||
backgroundColor: String? = null,
|
||||
) = Block(
|
||||
id = id,
|
||||
fields = fields,
|
||||
content = content,
|
||||
children = children,
|
||||
backgroundColor = backgroundColor
|
||||
)
|
||||
|
||||
fun makeOnePageWithTitleAndOnePageLinkBlock(
|
||||
rootId: String,
|
||||
titleBlockId: String,
|
||||
|
@ -223,10 +239,13 @@ object MockBlockFactory {
|
|||
Block(
|
||||
id = pageBlockId,
|
||||
fields = Block.Fields(emptyMap()),
|
||||
content = Block.Content.Link(
|
||||
content = Link(
|
||||
target = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
type = Block.Content.Link.Type.PAGE
|
||||
type = Link.Type.PAGE,
|
||||
iconSize = Link.IconSize.SMALL,
|
||||
cardStyle = Link.CardStyle.TEXT,
|
||||
description = Link.Description.NONE,
|
||||
relations = emptySet()
|
||||
),
|
||||
children = emptyList()
|
||||
)
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
package com.anytypeio.anytype.presentation.dashboard
|
||||
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Event
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.core_models.Position
|
||||
import com.anytypeio.anytype.core_models.SmartBlockType
|
||||
import com.anytypeio.anytype.core_utils.ext.shift
|
||||
import com.anytypeio.anytype.domain.base.Either
|
||||
import com.anytypeio.anytype.domain.block.interactor.Move
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.presentation.MockBlockContentFactory.StubLinkContent
|
||||
import com.anytypeio.anytype.presentation.MockBlockFactory.link
|
||||
import com.anytypeio.anytype.presentation.mapper.toDashboardViews
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
import com.jraska.livedata.test
|
||||
|
@ -13,7 +19,11 @@ import kotlinx.coroutines.flow.flow
|
|||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.kotlin.*
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.eq
|
||||
import org.mockito.kotlin.times
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.verifyZeroInteractions
|
||||
|
||||
class DashboardDragAndDropTest : DashboardTestSetup() {
|
||||
|
||||
|
@ -35,35 +45,8 @@ class DashboardDragAndDropTest : DashboardTestSetup() {
|
|||
)
|
||||
|
||||
val pages = listOf(
|
||||
Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
fields = Block.Fields(map = mapOf("name" to MockDataFactory.randomString())),
|
||||
content = Block.Content.Link(
|
||||
target = MockDataFactory.randomUuid(),
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields(
|
||||
map = mapOf(
|
||||
"name" to MockDataFactory.randomString(),
|
||||
"icon" to MockDataFactory.randomString()
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
fields = Block.Fields(map = mapOf("name" to MockDataFactory.randomString())),
|
||||
content = Block.Content.Link(
|
||||
target = MockDataFactory.randomUuid(),
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields(
|
||||
map = mapOf(
|
||||
"name" to MockDataFactory.randomString()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
createBlockLink(),
|
||||
createBlockLink()
|
||||
)
|
||||
|
||||
val dashboard = Block(
|
||||
|
@ -144,34 +127,8 @@ class DashboardDragAndDropTest : DashboardTestSetup() {
|
|||
fun `should start dispatching drag-and-drop actions when the dragged item is dropped`() {
|
||||
|
||||
val pages = listOf(
|
||||
Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
fields = Block.Fields(map = mapOf("name" to MockDataFactory.randomString())),
|
||||
content = Block.Content.Link(
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
target = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields(
|
||||
map = mapOf(
|
||||
"name" to MockDataFactory.randomString()
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
fields = Block.Fields(map = mapOf("name" to MockDataFactory.randomString())),
|
||||
content = Block.Content.Link(
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
target = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields(
|
||||
map = mapOf(
|
||||
"name" to MockDataFactory.randomString(),
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
createBlockLink(),
|
||||
createBlockLink()
|
||||
)
|
||||
|
||||
val dashboard = Block(
|
||||
|
@ -227,48 +184,9 @@ class DashboardDragAndDropTest : DashboardTestSetup() {
|
|||
fun `should call move use-case for dropping the last block before the first block`() {
|
||||
|
||||
val links = listOf(
|
||||
Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
fields = Block.Fields(map = mapOf("name" to MockDataFactory.randomString())),
|
||||
content = Block.Content.Link(
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
target = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields(
|
||||
map = mapOf(
|
||||
"name" to MockDataFactory.randomString()
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
fields = Block.Fields(map = mapOf("name" to MockDataFactory.randomString())),
|
||||
content = Block.Content.Link(
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
target = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields(
|
||||
map = mapOf(
|
||||
"name" to MockDataFactory.randomString(),
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
fields = Block.Fields(map = mapOf("name" to MockDataFactory.randomString())),
|
||||
content = Block.Content.Link(
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
target = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields(
|
||||
map = mapOf(
|
||||
"name" to MockDataFactory.randomString(),
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
createBlockLink(),
|
||||
createBlockLink(),
|
||||
createBlockLink()
|
||||
)
|
||||
|
||||
val dashboard = Block(
|
||||
|
@ -324,48 +242,9 @@ class DashboardDragAndDropTest : DashboardTestSetup() {
|
|||
fun `should call move use-case for dropping the first block after the second block`() {
|
||||
|
||||
val links = listOf(
|
||||
Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
fields = Block.Fields(map = mapOf("name" to MockDataFactory.randomString())),
|
||||
content = Block.Content.Link(
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
target = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields(
|
||||
map = mapOf(
|
||||
"name" to MockDataFactory.randomString()
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
fields = Block.Fields(map = mapOf("name" to MockDataFactory.randomString())),
|
||||
content = Block.Content.Link(
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
target = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields(
|
||||
map = mapOf(
|
||||
"name" to MockDataFactory.randomString(),
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
fields = Block.Fields(map = mapOf("name" to MockDataFactory.randomString())),
|
||||
content = Block.Content.Link(
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
target = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields(
|
||||
map = mapOf(
|
||||
"name" to MockDataFactory.randomString(),
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
createBlockLink(),
|
||||
createBlockLink(),
|
||||
createBlockLink()
|
||||
)
|
||||
|
||||
val dashboard = Block(
|
||||
|
@ -421,48 +300,9 @@ class DashboardDragAndDropTest : DashboardTestSetup() {
|
|||
fun `should call move use-case for dropping the first block after the third block`() {
|
||||
|
||||
val links = listOf(
|
||||
Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
fields = Block.Fields(map = mapOf("name" to MockDataFactory.randomString())),
|
||||
content = Block.Content.Link(
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
target = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields(
|
||||
map = mapOf(
|
||||
"name" to MockDataFactory.randomString()
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
fields = Block.Fields(map = mapOf("name" to MockDataFactory.randomString())),
|
||||
content = Block.Content.Link(
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
target = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields(
|
||||
map = mapOf(
|
||||
"name" to MockDataFactory.randomString(),
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
fields = Block.Fields(map = mapOf("name" to MockDataFactory.randomString())),
|
||||
content = Block.Content.Link(
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
target = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields(
|
||||
map = mapOf(
|
||||
"name" to MockDataFactory.randomString(),
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
createBlockLink(),
|
||||
createBlockLink(),
|
||||
createBlockLink()
|
||||
)
|
||||
|
||||
val dashboard = Block(
|
||||
|
@ -513,4 +353,12 @@ class DashboardDragAndDropTest : DashboardTestSetup() {
|
|||
onResult = any()
|
||||
)
|
||||
}
|
||||
|
||||
fun createBlockLink(): Block =
|
||||
link(
|
||||
fields = Block.Fields(map = mapOf("name" to MockDataFactory.randomString())),
|
||||
content = StubLinkContent(
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
)
|
||||
)
|
||||
}
|
|
@ -32,6 +32,8 @@ import com.anytypeio.anytype.domain.page.CreatePage
|
|||
import com.anytypeio.anytype.domain.search.CancelSearchSubscription
|
||||
import com.anytypeio.anytype.domain.search.ObjectSearchSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.templates.GetTemplates
|
||||
import com.anytypeio.anytype.presentation.MockBlockContentFactory.StubLinkContent
|
||||
import com.anytypeio.anytype.presentation.MockBlockFactory.link
|
||||
import com.anytypeio.anytype.presentation.navigation.AppNavigation
|
||||
import com.anytypeio.anytype.presentation.util.CoroutinesTestRule
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
|
@ -284,15 +286,8 @@ class HomeDashboardViewModelTest {
|
|||
|
||||
val targetId = MockDataFactory.randomUuid()
|
||||
|
||||
val page = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = emptyList(),
|
||||
fields = Block.Fields.empty(),
|
||||
content = Block.Content.Link(
|
||||
target = targetId,
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields.empty()
|
||||
)
|
||||
val page = link(
|
||||
content = StubLinkContent(target = targetId)
|
||||
)
|
||||
|
||||
val dashboard = Block(
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
package com.anytypeio.anytype.presentation.editor
|
||||
|
||||
import android.util.Log
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Block.Content.Link
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_models.SmartBlockType
|
||||
import com.anytypeio.anytype.core_models.ext.asMap
|
||||
import com.anytypeio.anytype.core_models.ext.content
|
||||
import com.anytypeio.anytype.core_models.restrictions.ObjectRestriction
|
||||
|
@ -10,6 +15,8 @@ import com.anytypeio.anytype.domain.config.Gateway
|
|||
import com.anytypeio.anytype.domain.editor.Editor
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.emojifier.data.DefaultDocumentEmojiIconProvider
|
||||
import com.anytypeio.anytype.presentation.MockBlockContentFactory.StubLinkContent
|
||||
import com.anytypeio.anytype.presentation.MockBlockFactory.link
|
||||
import com.anytypeio.anytype.presentation.MockTypicalDocumentFactory
|
||||
import com.anytypeio.anytype.presentation.editor.cover.CoverImageHashProvider
|
||||
import com.anytypeio.anytype.presentation.editor.editor.Markup
|
||||
|
@ -2420,23 +2427,13 @@ class DefaultBlockViewRendererTest {
|
|||
val header = MockTypicalDocumentFactory.header
|
||||
val target = MockDataFactory.randomUuid()
|
||||
|
||||
val a = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
children = listOf(),
|
||||
content = Block.Content.Link(
|
||||
val a = link(
|
||||
content = StubLinkContent(
|
||||
target = target,
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields.empty()
|
||||
),
|
||||
fields = Block.Fields(
|
||||
mapOf(
|
||||
"withIcon" to false,
|
||||
"withCover" to true,
|
||||
"withDescription" to true,
|
||||
"withName" to true,
|
||||
"iconSize" to 1.0,
|
||||
"style" to 1.0
|
||||
)
|
||||
cardStyle = Link.CardStyle.CARD,
|
||||
iconSize = Link.IconSize.NONE,
|
||||
description = Link.Description.ADDED,
|
||||
relations = setOf(Link.Relation.NAME)
|
||||
),
|
||||
backgroundColor = "red"
|
||||
)
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package com.anytypeio.anytype.presentation.editor
|
||||
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Block.Fields.Companion.NAME_KEY
|
||||
import com.anytypeio.anytype.core_models.Block.Content.Link.IconSize
|
||||
import com.anytypeio.anytype.core_models.Event
|
||||
import com.anytypeio.anytype.core_models.ext.content
|
||||
import com.anytypeio.anytype.presentation.MockBlockContentFactory.StubLinkContent
|
||||
import com.anytypeio.anytype.presentation.MockBlockFactory
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Test
|
||||
|
@ -216,31 +218,11 @@ class DocumentExternalEventReducerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `should update link fields`() {
|
||||
|
||||
val title = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Text(
|
||||
text = MockDataFactory.randomString(),
|
||||
marks = emptyList(),
|
||||
style = Block.Content.Text.Style.TITLE
|
||||
)
|
||||
)
|
||||
|
||||
val name = MockDataFactory.randomString()
|
||||
|
||||
val link = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Link(
|
||||
fields = Block.Fields(
|
||||
map = mapOf(NAME_KEY to name)
|
||||
),
|
||||
target = MockDataFactory.randomUuid(),
|
||||
type = Block.Content.Link.Type.PAGE
|
||||
fun `should update link appearance`() {
|
||||
val title = MockBlockFactory.title()
|
||||
val link = MockBlockFactory.link(
|
||||
content = StubLinkContent(
|
||||
iconSize = IconSize.NONE
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -257,8 +239,8 @@ class DocumentExternalEventReducerTest {
|
|||
|
||||
// TESTING
|
||||
|
||||
val updated = Block.Fields(
|
||||
map = mapOf(NAME_KEY to MockDataFactory.randomString())
|
||||
val updated = link.content.asLink().copy(
|
||||
iconSize = IconSize.MEDIUM
|
||||
)
|
||||
|
||||
runBlocking {
|
||||
|
@ -267,9 +249,7 @@ class DocumentExternalEventReducerTest {
|
|||
page,
|
||||
title,
|
||||
link.copy(
|
||||
content = link.content<Block.Content.Link>().copy(
|
||||
fields = updated
|
||||
)
|
||||
content = updated
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -279,7 +259,10 @@ class DocumentExternalEventReducerTest {
|
|||
context = page.id,
|
||||
id = link.id,
|
||||
target = link.content<Block.Content.Link>().target,
|
||||
fields = updated
|
||||
iconSize = IconSize.MEDIUM,
|
||||
cardStyle = null,
|
||||
description = null,
|
||||
relations = null
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import com.anytypeio.anytype.presentation.MockBlockFactory
|
|||
import com.anytypeio.anytype.presentation.editor.editor.actions.ActionItemType
|
||||
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
|
||||
import com.anytypeio.anytype.presentation.util.CoroutinesTestRule
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
@ -33,17 +32,7 @@ class EditorBlockActionsTest : EditorPresentationTestSetup() {
|
|||
@Test
|
||||
fun `preview action should be in actions before style - when link block`() {
|
||||
|
||||
val link = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Link(
|
||||
target = MockDataFactory.randomUuid(),
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields.empty()
|
||||
),
|
||||
backgroundColor = null
|
||||
)
|
||||
val link = MockBlockFactory.link()
|
||||
|
||||
val smart = Block(
|
||||
id = root,
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.anytypeio.anytype.core_models.Relations
|
|||
import com.anytypeio.anytype.core_models.SmartBlockType
|
||||
import com.anytypeio.anytype.core_models.ext.content
|
||||
import com.anytypeio.anytype.core_utils.common.EventWrapper
|
||||
import com.anytypeio.anytype.presentation.MockBlockFactory
|
||||
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.navigation.AppNavigation
|
||||
|
@ -234,21 +235,9 @@ class EditorLockPageTest : EditorPresentationTestSetup() {
|
|||
|
||||
@Test
|
||||
fun `should navigate to target when clicking on link-to-object when page is locked`() {
|
||||
|
||||
// SETUP
|
||||
|
||||
val target = MockDataFactory.randomUuid()
|
||||
|
||||
val link = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields(emptyMap()),
|
||||
content = Block.Content.Link(
|
||||
target = target,
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields.empty()
|
||||
),
|
||||
children = emptyList()
|
||||
)
|
||||
val link = MockBlockFactory.link()
|
||||
val target = link.content.asLink().target
|
||||
|
||||
val page = listOf(
|
||||
Block(
|
||||
|
|
|
@ -9,7 +9,9 @@ import com.anytypeio.anytype.domain.block.interactor.TurnIntoStyle
|
|||
import com.anytypeio.anytype.domain.block.interactor.UnlinkBlocks
|
||||
import com.anytypeio.anytype.domain.block.interactor.UpdateTextStyle
|
||||
import com.anytypeio.anytype.domain.clipboard.Copy
|
||||
import com.anytypeio.anytype.presentation.MockBlockContentFactory.StubLinkContent
|
||||
import com.anytypeio.anytype.presentation.MockBlockFactory
|
||||
import com.anytypeio.anytype.presentation.MockBlockFactory.link
|
||||
import com.anytypeio.anytype.presentation.editor.EditorViewModel
|
||||
import com.anytypeio.anytype.presentation.editor.EditorViewModel.Companion.DELAY_REFRESH_DOCUMENT_TO_ENTER_MULTI_SELECT_MODE
|
||||
import com.anytypeio.anytype.presentation.editor.EditorViewModel.Companion.TEXT_CHANGES_DEBOUNCE_DURATION
|
||||
|
@ -1308,28 +1310,18 @@ class EditorMultiSelectModeTest : EditorPresentationTestSetup() {
|
|||
fun `should start background style toolbar with null color when all blocks are not texted`() {
|
||||
val targetA = MockDataFactory.randomUuid()
|
||||
val backgroundA = "red"
|
||||
val a = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Link(
|
||||
val a = link(
|
||||
content = StubLinkContent(
|
||||
target = targetA,
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields.empty()
|
||||
),
|
||||
backgroundColor = backgroundA
|
||||
)
|
||||
|
||||
val targetB = MockDataFactory.randomUuid()
|
||||
val backgroundB = "teal"
|
||||
val b = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Link(
|
||||
val b = link(
|
||||
content = StubLinkContent(
|
||||
target = targetB,
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields.empty()
|
||||
),
|
||||
backgroundColor = backgroundB
|
||||
)
|
||||
|
@ -1389,43 +1381,10 @@ class EditorMultiSelectModeTest : EditorPresentationTestSetup() {
|
|||
|
||||
@Test
|
||||
fun `should start background style toolbar with red color when all blocks are not texted`() {
|
||||
val targetA = MockDataFactory.randomUuid()
|
||||
val backgroundA = "red"
|
||||
val a = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Link(
|
||||
target = targetA,
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields.empty()
|
||||
),
|
||||
backgroundColor = backgroundA
|
||||
)
|
||||
|
||||
val targetB = MockDataFactory.randomUuid()
|
||||
val b = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Link(
|
||||
target = targetB,
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields.empty()
|
||||
),
|
||||
backgroundColor = backgroundA
|
||||
)
|
||||
|
||||
val c = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.File(
|
||||
state = Block.Content.File.State.EMPTY
|
||||
),
|
||||
backgroundColor = backgroundA
|
||||
)
|
||||
|
||||
val a = link(backgroundColor = backgroundA)
|
||||
val b = link(backgroundColor = backgroundA)
|
||||
val c = link(backgroundColor = backgroundA)
|
||||
val page = Block(
|
||||
id = root,
|
||||
fields = Block.Fields(emptyMap()),
|
||||
|
@ -1470,44 +1429,10 @@ class EditorMultiSelectModeTest : EditorPresentationTestSetup() {
|
|||
|
||||
@Test
|
||||
fun `should start background style toolbar with red color when blocks are mixed`() {
|
||||
val targetA = MockDataFactory.randomUuid()
|
||||
val backgroundA = "red"
|
||||
val a = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Link(
|
||||
target = targetA,
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields.empty()
|
||||
),
|
||||
backgroundColor = backgroundA
|
||||
)
|
||||
|
||||
val targetB = MockDataFactory.randomUuid()
|
||||
val b = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Link(
|
||||
target = targetB,
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields.empty()
|
||||
),
|
||||
backgroundColor = backgroundA
|
||||
)
|
||||
|
||||
val c = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Link(
|
||||
target = targetA,
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields.empty()
|
||||
),
|
||||
backgroundColor = backgroundA
|
||||
)
|
||||
val a = link(backgroundColor = backgroundA)
|
||||
val b = link(backgroundColor = backgroundA)
|
||||
val c = link(backgroundColor = backgroundA)
|
||||
|
||||
val page = Block(
|
||||
id = root,
|
||||
|
@ -1553,42 +1478,9 @@ class EditorMultiSelectModeTest : EditorPresentationTestSetup() {
|
|||
|
||||
@Test
|
||||
fun `should start background style toolbar with default color when all blocks has nullable backgrounds`() {
|
||||
val targetA = MockDataFactory.randomUuid()
|
||||
val a = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Link(
|
||||
target = targetA,
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields.empty()
|
||||
),
|
||||
backgroundColor = null
|
||||
)
|
||||
|
||||
val b = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Text(
|
||||
text = MockDataFactory.randomString(),
|
||||
marks = emptyList(),
|
||||
style = Block.Content.Text.Style.P
|
||||
),
|
||||
backgroundColor = null
|
||||
)
|
||||
|
||||
val c = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Link(
|
||||
target = targetA,
|
||||
type = Block.Content.Link.Type.PAGE,
|
||||
fields = Block.Fields.empty()
|
||||
),
|
||||
backgroundColor = null
|
||||
)
|
||||
val a = link()
|
||||
val b = link()
|
||||
val c = link()
|
||||
|
||||
val page = Block(
|
||||
id = root,
|
||||
|
|
|
@ -8,7 +8,6 @@ import com.anytypeio.anytype.core_models.ObjectType
|
|||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.core_models.Relation
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_models.restrictions.ObjectRestriction
|
||||
import com.anytypeio.anytype.domain.`object`.ObjectTypesProvider
|
||||
import com.anytypeio.anytype.domain.`object`.UpdateDetail
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.anytypeio.anytype.core_models.Block
|
|||
import com.anytypeio.anytype.core_models.Position
|
||||
import com.anytypeio.anytype.core_models.ext.content
|
||||
import com.anytypeio.anytype.domain.block.interactor.Move
|
||||
import com.anytypeio.anytype.presentation.MockBlockFactory.link
|
||||
import com.anytypeio.anytype.presentation.editor.EditorViewModel
|
||||
import com.anytypeio.anytype.presentation.editor.editor.actions.ActionItemType
|
||||
import com.anytypeio.anytype.presentation.editor.editor.control.ControlPanelState
|
||||
|
@ -525,16 +526,7 @@ class EditorScrollAndMoveTest : EditorPresentationTestSetup() {
|
|||
)
|
||||
)
|
||||
|
||||
val b = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
children = emptyList(),
|
||||
content = Block.Content.Link(
|
||||
target = MockDataFactory.randomUuid(),
|
||||
fields = Block.Fields.empty(),
|
||||
type = Block.Content.Link.Type.PAGE
|
||||
)
|
||||
)
|
||||
val b = link()
|
||||
|
||||
val page = Block(
|
||||
id = root,
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package com.anytypeio.anytype.presentation.mapper
|
||||
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.domain.config.Gateway
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.editor.editor.Markup
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.objects.appearance.getLinkToObjectAppearanceParams
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
@ -82,7 +80,8 @@ class MapperExtensionKtTest {
|
|||
type = type
|
||||
)
|
||||
|
||||
val expected = BlockView.MediaPlaceholder.File(id = id, indent = indent, isPreviousBlockMedia = false)
|
||||
val expected =
|
||||
BlockView.MediaPlaceholder.File(id = id, indent = indent, isPreviousBlockMedia = false)
|
||||
val actual = block.toFileView(id, urlBuilder, indent, mode, false, null, false)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
|
@ -190,7 +189,11 @@ class MapperExtensionKtTest {
|
|||
|
||||
)
|
||||
|
||||
val expected = BlockView.MediaPlaceholder.Picture(id = id, indent = indent, isPreviousBlockMedia = false)
|
||||
val expected = BlockView.MediaPlaceholder.Picture(
|
||||
id = id,
|
||||
indent = indent,
|
||||
isPreviousBlockMedia = false
|
||||
)
|
||||
val actual = block.toPictureView(id, urlBuilder, indent, mode, false, null, false)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
|
@ -752,163 +755,4 @@ class MapperExtensionKtTest {
|
|||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should create appearance params with default values`() {
|
||||
val emptyFields = Block.Fields(mapOf())
|
||||
val layout = ObjectType.Layout.BASIC
|
||||
|
||||
val result = emptyFields.getLinkToObjectAppearanceParams(layout)
|
||||
|
||||
val expected = BlockView.Appearance.Params(
|
||||
style = BlockView.Appearance.LINK_STYLE_TEXT,
|
||||
iconSize = BlockView.Appearance.LINK_ICON_SIZE_MEDIUM,
|
||||
withIcon = true,
|
||||
withName = true,
|
||||
withDescription = null,
|
||||
canHaveCover = false,
|
||||
canHaveDescription = true,
|
||||
canHaveIcon = true
|
||||
)
|
||||
assertEquals(expected, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should create appearance params with default values when layout is null`() {
|
||||
val emptyFields = Block.Fields(mapOf())
|
||||
val layout = null
|
||||
|
||||
val result = emptyFields.getLinkToObjectAppearanceParams(layout)
|
||||
|
||||
val expected = BlockView.Appearance.Params(
|
||||
style = BlockView.Appearance.LINK_STYLE_TEXT,
|
||||
iconSize = BlockView.Appearance.LINK_ICON_SIZE_MEDIUM,
|
||||
withIcon = true,
|
||||
withName = true,
|
||||
withDescription = null,
|
||||
canHaveCover = false,
|
||||
canHaveDescription = true,
|
||||
canHaveIcon = true
|
||||
)
|
||||
assertEquals(expected, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should create appearance params with random values`() {
|
||||
val emptyFields = Block.Fields(
|
||||
mapOf(
|
||||
"withName" to false,
|
||||
"withIcon" to null,
|
||||
"withDescription" to true,
|
||||
"withCover" to true,
|
||||
"style" to BlockView.Appearance.LINK_STYLE_CARD,
|
||||
"iconSize" to BlockView.Appearance.LINK_ICON_SIZE_MEDIUM
|
||||
)
|
||||
)
|
||||
val layout = ObjectType.Layout.BASIC
|
||||
|
||||
val result = emptyFields.getLinkToObjectAppearanceParams(layout)
|
||||
|
||||
val expected = BlockView.Appearance.Params(
|
||||
style = BlockView.Appearance.LINK_STYLE_CARD,
|
||||
iconSize = BlockView.Appearance.LINK_ICON_SIZE_MEDIUM,
|
||||
withIcon = true,
|
||||
withName = false,
|
||||
withDescription = true,
|
||||
withCover = true,
|
||||
canHaveCover = false,
|
||||
canHaveDescription = true,
|
||||
canHaveIcon = true
|
||||
)
|
||||
assertEquals(expected, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should create appearance params without cover`() {
|
||||
val emptyFields = Block.Fields(
|
||||
mapOf(
|
||||
"withName" to false,
|
||||
"withIcon" to null,
|
||||
"withDescription" to true,
|
||||
"withCover" to true,
|
||||
"style" to BlockView.Appearance.LINK_STYLE_TEXT,
|
||||
"iconSize" to BlockView.Appearance.LINK_ICON_SIZE_MEDIUM
|
||||
)
|
||||
)
|
||||
val layout = ObjectType.Layout.BASIC
|
||||
|
||||
val result = emptyFields.getLinkToObjectAppearanceParams(layout)
|
||||
|
||||
val expected = BlockView.Appearance.Params(
|
||||
style = BlockView.Appearance.LINK_STYLE_TEXT,
|
||||
iconSize = BlockView.Appearance.LINK_ICON_SIZE_MEDIUM,
|
||||
withIcon = true,
|
||||
withName = false,
|
||||
withDescription = true,
|
||||
withCover = true,
|
||||
canHaveCover = false,
|
||||
canHaveDescription = false,
|
||||
canHaveIcon = true
|
||||
)
|
||||
assertEquals(expected, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should create appearance params when layout is todo`() {
|
||||
val emptyFields = Block.Fields(
|
||||
mapOf(
|
||||
"withName" to false,
|
||||
"withIcon" to false,
|
||||
"withDescription" to true,
|
||||
"withCover" to true,
|
||||
"style" to BlockView.Appearance.LINK_STYLE_TEXT,
|
||||
"iconSize" to BlockView.Appearance.LINK_ICON_SIZE_MEDIUM
|
||||
)
|
||||
)
|
||||
val layout = ObjectType.Layout.TODO
|
||||
|
||||
val result = emptyFields.getLinkToObjectAppearanceParams(layout)
|
||||
|
||||
val expected = BlockView.Appearance.Params(
|
||||
style = BlockView.Appearance.LINK_STYLE_TEXT,
|
||||
iconSize = BlockView.Appearance.LINK_ICON_SIZE_MEDIUM,
|
||||
withIcon = true,
|
||||
withName = false,
|
||||
withDescription = true,
|
||||
withCover = true,
|
||||
canHaveCover = false,
|
||||
canHaveDescription = false,
|
||||
canHaveIcon = false
|
||||
)
|
||||
assertEquals(expected, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should create appearance params when layout is note`() {
|
||||
val emptyFields = Block.Fields(
|
||||
mapOf(
|
||||
"withIcon" to true,
|
||||
"withDescription" to true,
|
||||
"withCover" to true,
|
||||
"style" to BlockView.Appearance.LINK_STYLE_TEXT,
|
||||
"iconSize" to BlockView.Appearance.LINK_ICON_SIZE_LARGE
|
||||
)
|
||||
)
|
||||
val layout = ObjectType.Layout.NOTE
|
||||
|
||||
val result = emptyFields.getLinkToObjectAppearanceParams(layout)
|
||||
|
||||
val expected = BlockView.Appearance.Params(
|
||||
style = BlockView.Appearance.LINK_STYLE_TEXT,
|
||||
iconSize = BlockView.Appearance.LINK_ICON_SIZE_MEDIUM,
|
||||
withIcon = false,
|
||||
withName = true,
|
||||
withDescription = false,
|
||||
withCover = false,
|
||||
canHaveCover = false,
|
||||
canHaveDescription = false,
|
||||
canHaveIcon = false
|
||||
)
|
||||
assertEquals(expected, result)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
package com.anytypeio.anytype.presentation.objects.appearance
|
||||
|
||||
import com.anytypeio.anytype.core_models.Block.Content.Link
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.presentation.MockBlockContentFactory.StubLinkContent
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class LinkAppearanceInEditorTest {
|
||||
|
||||
private val defaultLinkAppearance = StubLinkContent(
|
||||
iconSize = Link.IconSize.NONE,
|
||||
cardStyle = Link.CardStyle.TEXT,
|
||||
description = Link.Description.NONE,
|
||||
relations = emptySet()
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `should create appearance params with default values`() {
|
||||
|
||||
val factory = LinkAppearanceFactory(
|
||||
content = defaultLinkAppearance,
|
||||
layout = ObjectType.Layout.BASIC
|
||||
)
|
||||
|
||||
val actual = factory.createInEditorLinkAppearance()
|
||||
val expected = BlockView.Appearance.InEditor(
|
||||
isCard = false,
|
||||
showIcon = false,
|
||||
showName = true,
|
||||
showDescription = false,
|
||||
showCover = false,
|
||||
)
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when layout is null - create appearance params with default values`() {
|
||||
val factory = LinkAppearanceFactory(
|
||||
content = defaultLinkAppearance,
|
||||
layout = null
|
||||
)
|
||||
|
||||
val actual = factory.createInEditorLinkAppearance()
|
||||
val expected = BlockView.Appearance.InEditor(
|
||||
isCard = false,
|
||||
showIcon = false,
|
||||
showName = true,
|
||||
showDescription = false,
|
||||
showCover = false,
|
||||
)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should create appearance params without cover`() {
|
||||
val factory = LinkAppearanceFactory(
|
||||
content = defaultLinkAppearance.copy(
|
||||
relations = defaultLinkAppearance.relations + Link.Relation.COVER
|
||||
),
|
||||
layout = ObjectType.Layout.BASIC
|
||||
)
|
||||
|
||||
val actual = factory.createInEditorLinkAppearance()
|
||||
|
||||
val expected = BlockView.Appearance.InEditor(
|
||||
isCard = false,
|
||||
showIcon = false,
|
||||
showName = true,
|
||||
showDescription = false,
|
||||
showCover = false,
|
||||
)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when layout is todo`() {
|
||||
val factory = LinkAppearanceFactory(
|
||||
content = defaultLinkAppearance,
|
||||
layout = ObjectType.Layout.TODO
|
||||
)
|
||||
|
||||
val actual = factory.createInEditorLinkAppearance()
|
||||
|
||||
val expected = BlockView.Appearance.InEditor(
|
||||
isCard = false,
|
||||
showIcon = true,
|
||||
showName = true,
|
||||
showDescription = false,
|
||||
showCover = false,
|
||||
)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when layout is note`() {
|
||||
val factory = LinkAppearanceFactory(
|
||||
content = defaultLinkAppearance.copy(
|
||||
iconSize = Link.IconSize.SMALL
|
||||
),
|
||||
layout = ObjectType.Layout.NOTE
|
||||
)
|
||||
|
||||
val actual = factory.createInEditorLinkAppearance()
|
||||
|
||||
val expected = BlockView.Appearance.InEditor(
|
||||
isCard = false,
|
||||
showIcon = false,
|
||||
showName = true,
|
||||
showDescription = false,
|
||||
showCover = false,
|
||||
)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when iconSize is none - no icon`() {
|
||||
val factory = LinkAppearanceFactory(
|
||||
content = defaultLinkAppearance.copy(
|
||||
iconSize = Link.IconSize.NONE
|
||||
),
|
||||
layout = ObjectType.Layout.BASIC
|
||||
)
|
||||
|
||||
val actual = factory.createInEditorLinkAppearance()
|
||||
|
||||
val expected = BlockView.Appearance.InEditor(
|
||||
isCard = false,
|
||||
showIcon = false,
|
||||
showName = true,
|
||||
showDescription = false,
|
||||
showCover = false,
|
||||
)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when card style text - no description`() {
|
||||
val factory = LinkAppearanceFactory(
|
||||
content = defaultLinkAppearance.copy(
|
||||
cardStyle = Link.CardStyle.TEXT,
|
||||
description = Link.Description.ADDED
|
||||
),
|
||||
layout = ObjectType.Layout.BASIC
|
||||
)
|
||||
|
||||
val actual = factory.createInEditorLinkAppearance()
|
||||
|
||||
val expected = BlockView.Appearance.InEditor(
|
||||
isCard = false,
|
||||
showIcon = false,
|
||||
showName = true,
|
||||
showDescription = false,
|
||||
showCover = false,
|
||||
)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
@Test
|
||||
fun `when card style card - there is description`() {
|
||||
val factory = LinkAppearanceFactory(
|
||||
content = defaultLinkAppearance.copy(
|
||||
cardStyle = Link.CardStyle.CARD,
|
||||
description = Link.Description.ADDED
|
||||
),
|
||||
layout = ObjectType.Layout.BASIC
|
||||
)
|
||||
|
||||
val actual = factory.createInEditorLinkAppearance()
|
||||
|
||||
val expected = BlockView.Appearance.InEditor(
|
||||
isCard = true,
|
||||
showIcon = false,
|
||||
showName = true,
|
||||
showDescription = true,
|
||||
showCover = false,
|
||||
)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package com.anytypeio.anytype.presentation.objects.appearance
|
||||
|
||||
import com.anytypeio.anytype.core_models.Block.Content.Link
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.presentation.MockBlockContentFactory.StubLinkContent
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.MenuItem
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class LinkAppearanceMenuTest {
|
||||
|
||||
private val defaultLinkAppearance = StubLinkContent(
|
||||
iconSize = Link.IconSize.SMALL,
|
||||
cardStyle = Link.CardStyle.TEXT,
|
||||
description = Link.Description.NONE,
|
||||
relations = setOf(Link.Relation.NAME)
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `default`() {
|
||||
val factory = LinkAppearanceFactory(
|
||||
content = defaultLinkAppearance,
|
||||
layout = ObjectType.Layout.BASIC
|
||||
)
|
||||
|
||||
val actual = factory.createAppearanceMenuItems()
|
||||
val expected = BlockView.Appearance.Menu(
|
||||
preview = MenuItem.PreviewLayout.TEXT,
|
||||
icon = MenuItem.Icon.SMALL,
|
||||
cover = null,
|
||||
description = null
|
||||
)
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when is todo layout - no icon`() {
|
||||
val factory = LinkAppearanceFactory(
|
||||
content = defaultLinkAppearance,
|
||||
layout = ObjectType.Layout.TODO
|
||||
)
|
||||
|
||||
val actual = factory.createAppearanceMenuItems()
|
||||
val expected = BlockView.Appearance.Menu(
|
||||
preview = MenuItem.PreviewLayout.TEXT,
|
||||
icon = null,
|
||||
cover = null,
|
||||
description = null
|
||||
)
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when is todo note - no icon and no description`() {
|
||||
val factory = LinkAppearanceFactory(
|
||||
content = defaultLinkAppearance.copy(
|
||||
description = Link.Description.ADDED
|
||||
),
|
||||
layout = ObjectType.Layout.NOTE
|
||||
)
|
||||
|
||||
val actual = factory.createAppearanceMenuItems()
|
||||
val expected = BlockView.Appearance.Menu(
|
||||
preview = MenuItem.PreviewLayout.TEXT,
|
||||
icon = null,
|
||||
cover = null,
|
||||
description = null
|
||||
)
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when card style is card - has description`() {
|
||||
val factory = LinkAppearanceFactory(
|
||||
content = defaultLinkAppearance.copy(
|
||||
description = Link.Description.ADDED,
|
||||
cardStyle = Link.CardStyle.CARD,
|
||||
),
|
||||
layout = ObjectType.Layout.BASIC
|
||||
)
|
||||
|
||||
val actual = factory.createAppearanceMenuItems()
|
||||
val expected = BlockView.Appearance.Menu(
|
||||
preview = MenuItem.PreviewLayout.CARD,
|
||||
icon = MenuItem.Icon.SMALL,
|
||||
cover = null,
|
||||
description = MenuItem.Description.WITH
|
||||
)
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue