mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-2206 Sets | Display filters for relations with the File format. (#1349)
This commit is contained in:
parent
6c411a919f
commit
31e4703ad6
39 changed files with 360 additions and 300 deletions
|
@ -49,6 +49,7 @@ open class ViewerFilterFragment : BaseBottomSheetFragment<FragmentFilterBinding>
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
expand()
|
||||
binding.recycler.layoutManager = LinearLayoutManager(requireContext())
|
||||
binding.recycler.adapter = filterAdapter
|
||||
with(lifecycleScope) {
|
||||
|
|
|
@ -16,13 +16,13 @@ import com.anytypeio.anytype.core_utils.ext.drawable
|
|||
import com.anytypeio.anytype.core_utils.ext.invisible
|
||||
import com.anytypeio.anytype.core_utils.ext.subscribe
|
||||
import com.anytypeio.anytype.core_utils.ext.visible
|
||||
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetTextInputFragment
|
||||
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
|
||||
import com.anytypeio.anytype.databinding.FragmentSelectSortOrFilterRelationBinding
|
||||
import com.anytypeio.anytype.presentation.sets.SearchRelationViewModel
|
||||
import com.anytypeio.anytype.presentation.sets.model.SimpleRelationView
|
||||
|
||||
abstract class SearchRelationFragment :
|
||||
BaseBottomSheetTextInputFragment<FragmentSelectSortOrFilterRelationBinding>() {
|
||||
BaseBottomSheetFragment<FragmentSelectSortOrFilterRelationBinding>() {
|
||||
|
||||
abstract val ctx: String
|
||||
abstract val vm: SearchRelationViewModel
|
||||
|
@ -32,7 +32,7 @@ abstract class SearchRelationFragment :
|
|||
SearchRelationAdapter { relation -> onRelationClicked(ctx = ctx, relation = relation) }
|
||||
}
|
||||
|
||||
override val textInput: EditText get() = binding.searchBar.root.findViewById(R.id.filterInputField)
|
||||
val textInput: EditText get() = binding.searchBar.root.findViewById(R.id.filterInputField)
|
||||
|
||||
lateinit var searchRelationInput: EditText
|
||||
lateinit var clearSearchText: View
|
||||
|
@ -41,6 +41,8 @@ abstract class SearchRelationFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setFullHeightSheet()
|
||||
skipCollapsed()
|
||||
searchRelationInput = binding.searchBar.root.findViewById(R.id.filterInputField)
|
||||
searchRelationInput.apply {
|
||||
hint = getString(R.string.choose_relation_to_filter)
|
||||
|
@ -74,6 +76,7 @@ abstract class SearchRelationFragment :
|
|||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
expand()
|
||||
vm.onStart(viewerId = viewer)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--typography, buttons 05.04-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
|
@ -99,9 +98,10 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginTop="@dimen/dp_6"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_marginBottom="@dimen/dp_10"
|
||||
android:layout_marginBottom="@dimen/dp_20"
|
||||
app:buttonTitle="@string/apply">
|
||||
</com.anytypeio.anytype.core_ui.widgets.ButtonPrimaryNumber>
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--typography, buttons 05.04-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -2,8 +2,9 @@ package com.anytypeio.anytype.core_ui.features.dataview.modals
|
|||
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.databinding.ItemDvViewerFilterObjectBinding
|
||||
import com.anytypeio.anytype.core_ui.widgets.ObjectIconTextWidget
|
||||
import com.anytypeio.anytype.core_ui.widgets.ObjectIconWidget
|
||||
import com.anytypeio.anytype.core_ui.widgets.RelationFormatIconWidget
|
||||
import com.anytypeio.anytype.core_utils.ext.gone
|
||||
import com.anytypeio.anytype.core_utils.ext.visible
|
||||
|
@ -12,7 +13,8 @@ import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
|||
import com.anytypeio.anytype.presentation.sets.model.FilterView
|
||||
import com.anytypeio.anytype.presentation.sets.model.ObjectView
|
||||
|
||||
class FilterObjectViewHolder(val binding: ItemDvViewerFilterObjectBinding) : FilterViewHolder(binding.root) {
|
||||
class FilterObjectViewHolder(val binding: ItemDvViewerFilterObjectBinding) :
|
||||
FilterViewHolder(binding.root) {
|
||||
|
||||
override val textTitle: TextView get() = binding.tvTitle
|
||||
override val textCondition: TextView get() = binding.tvCondition
|
||||
|
@ -20,6 +22,10 @@ class FilterObjectViewHolder(val binding: ItemDvViewerFilterObjectBinding) : Fil
|
|||
override val iconArrow: ImageView get() = binding.iconArrow
|
||||
override val iconRemove: ImageView get() = binding.iconRemoveObject
|
||||
|
||||
private val objectIcon: ObjectIconWidget get() = binding.objectIcon
|
||||
private val number: TextView get() = binding.number
|
||||
private val objectName: TextView get() = binding.objectName
|
||||
|
||||
fun bind(item: FilterView.Expression.Object) = with(itemView) {
|
||||
setup(
|
||||
isEditMode = item.isInEditMode,
|
||||
|
@ -28,38 +34,39 @@ class FilterObjectViewHolder(val binding: ItemDvViewerFilterObjectBinding) : Fil
|
|||
format = item.format
|
||||
)
|
||||
|
||||
for (i in 0..MAX_VISIBLE_OBJECTS_INDEX) getViewByIndex(i)?.gone()
|
||||
if (item.condition.hasValue()) {
|
||||
item.filterValue.value.forEachIndexed { index, objectView ->
|
||||
if (objectView is ObjectView.Default) {
|
||||
when (index) {
|
||||
in 0..MAX_VISIBLE_OBJECTS_INDEX -> {
|
||||
getViewByIndex(index)?.let { view ->
|
||||
view.visible()
|
||||
view.setup(
|
||||
name = objectView.name,
|
||||
icon = objectView.icon
|
||||
)
|
||||
if (index == 0) {
|
||||
objectName.text = objectView.name.ifBlank {
|
||||
context.resources.getString(R.string.untitled)
|
||||
}
|
||||
when (objectView.icon) {
|
||||
ObjectIcon.None -> objectIcon.gone()
|
||||
else -> {
|
||||
objectIcon.visible()
|
||||
objectIcon.setIcon(objectView.icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i in 0..MAX_VISIBLE_OBJECTS_INDEX) getViewByIndex(i)?.apply {
|
||||
this.setup(name = null, icon = ObjectIcon.None)
|
||||
val valuesSize = item.filterValue.value.size
|
||||
|
||||
if (valuesSize > MAX_ITEMS) {
|
||||
number.visible()
|
||||
number.text = "+${valuesSize - MAX_ITEMS}"
|
||||
} else {
|
||||
number.gone()
|
||||
}
|
||||
} else {
|
||||
objectIcon.gone()
|
||||
number.gone()
|
||||
objectName.text = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getViewByIndex(index: Int): ObjectIconTextWidget? = when (index) {
|
||||
0 -> binding.object0
|
||||
1 -> binding.object1
|
||||
2 -> binding.object2
|
||||
else -> null
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MAX_VISIBLE_OBJECTS_INDEX = 2
|
||||
private const val MAX_ITEMS = 1
|
||||
}
|
||||
}
|
|
@ -38,6 +38,9 @@ class FilterStatusViewHolder(val binding: ItemDvViewerFilterStatusBinding) :
|
|||
if (status != null) {
|
||||
binding.tvValue.text = status.status
|
||||
setTextColor(binding.tvValue, status.color)
|
||||
} else {
|
||||
binding.tvValue.text = null
|
||||
binding.tvValue.invisible()
|
||||
}
|
||||
} else {
|
||||
binding.tvValue.text = null
|
||||
|
@ -47,7 +50,7 @@ class FilterStatusViewHolder(val binding: ItemDvViewerFilterStatusBinding) :
|
|||
|
||||
private fun setTextColor(view: TextView, color: String) {
|
||||
val defaultColor = view.context.color(R.color.default_filter_tag_text_color)
|
||||
val value = ThemeColor.values().find { value -> value.code == color }
|
||||
val value = ThemeColor.entries.find { value -> value.code == color }
|
||||
if (value == null) {
|
||||
Timber.w("Could not find value for text color: $color")
|
||||
}
|
||||
|
|
|
@ -1,24 +1,21 @@
|
|||
package com.anytypeio.anytype.core_ui.features.dataview.modals
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.anytypeio.anytype.core_models.ThemeColor
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.databinding.ItemDvViewerFilterTagBinding
|
||||
import com.anytypeio.anytype.core_ui.extensions.color
|
||||
import com.anytypeio.anytype.core_ui.extensions.dark
|
||||
import com.anytypeio.anytype.core_ui.extensions.light
|
||||
import com.anytypeio.anytype.core_ui.widgets.RelationFormatIconWidget
|
||||
import com.anytypeio.anytype.core_utils.ext.gone
|
||||
import com.anytypeio.anytype.core_utils.ext.invisible
|
||||
import com.anytypeio.anytype.core_utils.ext.setDrawableColor
|
||||
import com.anytypeio.anytype.core_utils.ext.visible
|
||||
import com.anytypeio.anytype.presentation.extension.hasValue
|
||||
import com.anytypeio.anytype.presentation.sets.model.FilterView
|
||||
import com.anytypeio.anytype.presentation.sets.model.TagView
|
||||
import com.google.android.material.chip.Chip
|
||||
|
||||
class FilterTagViewHolder(val binding: ItemDvViewerFilterTagBinding) : FilterViewHolder(binding.root) {
|
||||
class FilterTagViewHolder(val binding: ItemDvViewerFilterTagBinding) :
|
||||
FilterViewHolder(binding.root) {
|
||||
|
||||
override val textTitle: TextView get() = binding.tvTitle
|
||||
override val textCondition: TextView get() = binding.tvCondition
|
||||
|
@ -26,10 +23,8 @@ class FilterTagViewHolder(val binding: ItemDvViewerFilterTagBinding) : FilterVie
|
|||
override val iconArrow: ImageView get() = binding.iconArrow
|
||||
override val iconRemove: ImageView get() = binding.iconRemoveTag
|
||||
|
||||
private val chip1 = binding.tvValue.chip1
|
||||
private val chip2 = binding.tvValue.chip2
|
||||
private val chipDots = binding.tvValue.chipDots
|
||||
private val chips = listOf(chip1, chip2, chipDots)
|
||||
private val tagView = binding.tag
|
||||
private val numberView: TextView get() = binding.number
|
||||
|
||||
fun bind(
|
||||
item: FilterView.Expression.Tag
|
||||
|
@ -40,40 +35,45 @@ class FilterTagViewHolder(val binding: ItemDvViewerFilterTagBinding) : FilterVie
|
|||
condition = item.condition.title,
|
||||
format = item.format
|
||||
)
|
||||
chips.forEach { it.gone() }
|
||||
if (item.condition.hasValue()) {
|
||||
item.filterValue.value.forEachIndexed { index, s ->
|
||||
when (index) {
|
||||
0 -> bindChip(chip1, s)
|
||||
1 -> bindChip(chip2, s)
|
||||
2 -> chipDots.visible()
|
||||
}
|
||||
val valuesSize = item.filterValue.value.size
|
||||
if (item.filterValue.value.isNotEmpty()) {
|
||||
val tag = item.filterValue.value.first()
|
||||
val color = ThemeColor.entries.find { it.code == tag.color }
|
||||
setupTag(tagView, color, tag.tag)
|
||||
} else {
|
||||
tagView.gone()
|
||||
}
|
||||
if (valuesSize > MAX_ITEMS) {
|
||||
numberView.visible()
|
||||
numberView.text = "+${valuesSize - MAX_ITEMS}"
|
||||
} else {
|
||||
numberView.gone()
|
||||
}
|
||||
} else {
|
||||
bindChip(chip1, null)
|
||||
bindChip(chip2, null)
|
||||
chipDots.invisible()
|
||||
tagView.gone()
|
||||
numberView.gone()
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindChip(chip: Chip, value: TagView?) {
|
||||
with(chip) {
|
||||
val defaultTextColor = itemView.resources.getColor(R.color.text_primary, null)
|
||||
val defaultBackground = itemView.resources.getColor(R.color.shape_primary, null)
|
||||
val color = ThemeColor.values().find { v -> v.code == value?.color }
|
||||
if (color != null && color != ThemeColor.DEFAULT) {
|
||||
chipBackgroundColor = ColorStateList.valueOf(resources.light(color, defaultBackground))
|
||||
setTextColor(resources.dark(color, defaultTextColor))
|
||||
} else {
|
||||
setChipBackgroundColorResource(R.color.default_filter_tag_background_color)
|
||||
setTextColor(context.color(R.color.default_filter_tag_text_color))
|
||||
}
|
||||
text = value?.tag
|
||||
if (value != null) {
|
||||
visible()
|
||||
} else {
|
||||
invisible()
|
||||
}
|
||||
private fun setupTag(
|
||||
textView: TextView,
|
||||
color: ThemeColor?,
|
||||
txt: String
|
||||
) {
|
||||
textView.apply {
|
||||
visible()
|
||||
val textColorPrimary = resources.getColor(R.color.text_secondary, null)
|
||||
val defaultBackground = resources.getColor(R.color.shape_primary, null)
|
||||
setTextColor(color?.let { resources.dark(it, textColorPrimary) } ?: textColorPrimary)
|
||||
setBackgroundResource(R.drawable.rect_dv_cell_tag_item)
|
||||
background.setDrawableColor(color?.let { resources.light(it, defaultBackground) }
|
||||
?: defaultBackground)
|
||||
text = txt
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val MAX_ITEMS = 1
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package com.anytypeio.anytype.core_ui.widgets
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.databinding.WidgetObjectIconTextBinding
|
||||
import com.anytypeio.anytype.core_utils.ext.gone
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
|
||||
class ObjectIconTextWidget @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
||||
) : ConstraintLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
val binding = WidgetObjectIconTextBinding.inflate(
|
||||
LayoutInflater.from(context), this, true
|
||||
)
|
||||
|
||||
init {
|
||||
setupAttributeValues(attrs)
|
||||
}
|
||||
|
||||
private fun setupAttributeValues(set: AttributeSet?) {
|
||||
|
||||
val attrs = context.obtainStyledAttributes(set, R.styleable.ObjectIconTextWidget, 0, 0)
|
||||
|
||||
val nameTextSize = attrs.getDimensionPixelSize(R.styleable.ObjectIconTextWidget_nameTextSize, 0)
|
||||
if (nameTextSize > 0) {
|
||||
setTextSize(nameTextSize.toFloat())
|
||||
}
|
||||
|
||||
val nameTextColor = attrs.getColor(R.styleable.ObjectIconTextWidget_nameTextColor, 0)
|
||||
setTextColor(nameTextColor)
|
||||
|
||||
attrs.recycle()
|
||||
}
|
||||
|
||||
fun setTextSize(textSize: Float) {
|
||||
binding.objectName.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
|
||||
}
|
||||
|
||||
fun setTextColor(textColor: Int) {
|
||||
binding.objectName.setTextColor(textColor)
|
||||
}
|
||||
|
||||
fun setup(
|
||||
name: String?,
|
||||
icon: ObjectIcon = ObjectIcon.None
|
||||
) {
|
||||
binding.objectName.text = name
|
||||
binding.objectIcon.setIcon(icon)
|
||||
if (icon is ObjectIcon.None) {
|
||||
binding.objectIcon.gone()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -193,7 +193,7 @@ class RelationValueListWidget @JvmOverloads constructor(
|
|||
|
||||
private fun setupTags(relation: ObjectRelationView.Tags) {
|
||||
relation.tags.take(MAX_ITEMS).forEachIndexed { index, tag ->
|
||||
val color = ThemeColor.values().find { it.code == tag.color }
|
||||
val color = ThemeColor.entries.find { it.code == tag.color }
|
||||
if (index == 0) setupTag(text1, color, tag.tag)
|
||||
else setupTag(
|
||||
textView = text2.apply { maxWidth = maxTextWidth },
|
||||
|
@ -237,7 +237,7 @@ class RelationValueListWidget @JvmOverloads constructor(
|
|||
when {
|
||||
relation.status.isEmpty() -> setupSingleTextItem(name = relation.name)
|
||||
else -> {
|
||||
val color = ThemeColor.values().find { it.code == relation.status[0].color }
|
||||
val color = ThemeColor.entries.find { it.code == relation.status[0].color }
|
||||
val txt = relation.status[0].status
|
||||
setupStatus(text1, color, txt)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape android:shape="rectangle"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/shape_tertiary" />
|
||||
<solid android:color="@color/object_number_background" />
|
||||
<corners android:radius="3dp" />
|
||||
</shape>
|
|
@ -2,6 +2,6 @@
|
|||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:drawable="@drawable/divider_relations"
|
||||
android:left="80dp"
|
||||
android:left="20dp"
|
||||
android:right="20dp" />
|
||||
</layer-list>
|
|
@ -10,5 +10,5 @@
|
|||
android:fillColor="#00000000"
|
||||
android:pathData="M6,12L11,17L18,6"
|
||||
android:strokeWidth="1.5"
|
||||
android:strokeColor="#ffffff" />
|
||||
android:strokeColor="@color/text_button_label" />
|
||||
</vector>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconArrow"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconFormatContainer"
|
||||
|
@ -42,6 +42,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/iconFormatContainer"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconFormatContainer"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvTitle"
|
||||
tools:text="Is" />
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconArrow"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconFormatContainer"
|
||||
|
@ -42,6 +42,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/iconFormatContainer"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconFormatContainer"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvTitle"
|
||||
tools:text="Contains" />
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconArrow"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconFormatContainer"
|
||||
|
@ -42,6 +42,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/iconFormatContainer"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconFormatContainer"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvTitle"
|
||||
tools:text="Contains" />
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconArrow"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconFormatContainer"
|
||||
|
@ -43,53 +43,58 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/iconFormatContainer"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconFormatContainer"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvTitle"
|
||||
tools:text="Contains" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="22dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/tvCondition"
|
||||
app:layout_constraintEnd_toStartOf="@id/iconArrow"
|
||||
app:layout_constraintStart_toEndOf="@id/tvCondition"
|
||||
<com.anytypeio.anytype.core_ui.widgets.ObjectIconWidget
|
||||
android:id="@+id/objectIcon"
|
||||
style="@style/ObjectIcon15Style"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
app:emojiSize="18dp"
|
||||
app:imageSize="18dp"
|
||||
app:initialTextSize="11sp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tvCondition"
|
||||
app:layout_constraintStart_toEndOf="@+id/tvCondition"
|
||||
app:layout_constraintTop_toTopOf="@+id/tvCondition"
|
||||
app:layout_goneMarginEnd="@dimen/dp_20">
|
||||
tools:visibility="visible" />
|
||||
|
||||
<com.anytypeio.anytype.core_ui.widgets.ObjectIconTextWidget
|
||||
android:id="@+id/object0"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="22dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:visibility="gone"
|
||||
app:emojiSize="18dp"
|
||||
app:nameTextColor="#6C6A5F"
|
||||
app:nameTextSize="15sp"
|
||||
tools:visibility="visible" />
|
||||
<TextView
|
||||
android:id="@+id/objectName"
|
||||
style="@style/ViewerFilterObjectValueStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:gravity="bottom"
|
||||
android:maxWidth="150dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tvCondition"
|
||||
app:layout_constraintStart_toEndOf="@+id/objectIcon"
|
||||
app:layout_constraintTop_toTopOf="@+id/tvCondition"
|
||||
app:layout_goneMarginStart="8dp"
|
||||
tools:text="SomeFileNameName"/>
|
||||
|
||||
<com.anytypeio.anytype.core_ui.widgets.ObjectIconTextWidget
|
||||
android:id="@+id/object1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="22dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:visibility="gone"
|
||||
app:emojiSize="18dp"
|
||||
app:nameTextColor="#6C6A5F"
|
||||
app:nameTextSize="15sp"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<com.anytypeio.anytype.core_ui.widgets.ObjectIconTextWidget
|
||||
android:id="@+id/object2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="22dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:visibility="gone"
|
||||
app:emojiSize="18dp"
|
||||
app:nameTextColor="#6C6A5F"
|
||||
app:nameTextSize="15sp"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/number"
|
||||
style="@style/TextView.ContentStyle.Relations.2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_weight="0.8"
|
||||
android:background="@drawable/bg_relation_values_number"
|
||||
android:paddingStart="@dimen/dp_4"
|
||||
android:paddingEnd="@dimen/dp_4"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tvCondition"
|
||||
app:layout_constraintStart_toEndOf="@+id/objectName"
|
||||
app:layout_constraintTop_toTopOf="@+id/tvCondition"
|
||||
tools:text="+3"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iconArrow"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconArrow"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconFormatContainer"
|
||||
|
@ -42,6 +42,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/iconFormatContainer"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconFormatContainer"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvTitle"
|
||||
tools:text="Contains" />
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconArrow"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconFormatContainer"
|
||||
|
@ -42,22 +42,48 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/iconFormatContainer"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconFormatContainer"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvTitle"
|
||||
tools:text="Contains" />
|
||||
|
||||
<include
|
||||
android:id="@+id/tvValue"
|
||||
layout="@layout/item_dv_viewer_filter_tag_value"
|
||||
android:layout_width="0dp"
|
||||
<TextView
|
||||
android:id="@+id/tag"
|
||||
style="@style/TextView.ContentStyle.Relations.2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="6dp"
|
||||
android:ellipsize="middle"
|
||||
android:maxLength="25"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tvCondition"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconArrow"
|
||||
app:layout_constraintStart_toEndOf="@+id/tvCondition"
|
||||
app:layout_constraintTop_toTopOf="@+id/tvCondition"
|
||||
app:layout_goneMarginEnd="@dimen/dp_20" />
|
||||
tools:text="FavoritesFavoritesFavoritesFavorites"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/number"
|
||||
style="@style/TextView.ContentStyle.Relations.2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="0.8"
|
||||
android:background="@drawable/bg_relation_values_number"
|
||||
android:paddingStart="@dimen/dp_4"
|
||||
android:paddingEnd="@dimen/dp_4"
|
||||
android:textColor="@color/text_secondary"
|
||||
android:visibility="gone"
|
||||
android:layout_marginStart="6dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/tvCondition"
|
||||
app:layout_constraintStart_toEndOf="@+id/tag"
|
||||
app:layout_constraintTop_toTopOf="@+id/tvCondition"
|
||||
tools:text="+3"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iconArrow"
|
||||
|
|
|
@ -16,42 +16,10 @@
|
|||
app:chipMinTouchTargetSize="0dp"
|
||||
android:includeFontPadding="false"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/chip2"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="And" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chip2"
|
||||
style="@style/ViewerFilterTagChipStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/dv_viewer_filter_value_tag_height"
|
||||
android:layout_marginStart="4dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
app:chipMinTouchTargetSize="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/chip1"
|
||||
app:layout_constraintEnd_toStartOf="@+id/chipDots"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toEndOf="@+id/chip1"
|
||||
app:layout_constraintTop_toTopOf="@+id/chip1"
|
||||
tools:text="And" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chipDots"
|
||||
style="@style/ViewerFilterTagChipStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/dv_viewer_filter_value_tag_height"
|
||||
android:layout_marginStart="4dp"
|
||||
android:text="..."
|
||||
app:chipMinTouchTargetSize="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/chip2"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toEndOf="@+id/chip2"
|
||||
app:layout_constraintTop_toTopOf="@+id/chip2"
|
||||
tools:text="And" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -29,7 +29,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconArrow"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconFormatContainer"
|
||||
|
@ -42,6 +42,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/iconFormatContainer"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconFormatContainer"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvTitle"
|
||||
tools:text="Contains" />
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<com.anytypeio.anytype.core_ui.widgets.ObjectIconWidget
|
||||
android:id="@+id/objectIcon"
|
||||
style="@style/ObjectIcon15Style"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/objectName"
|
||||
style="@style/GridCellDateTextStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
app:layout_goneMarginStart="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/objectIcon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Feature" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -124,4 +124,6 @@
|
|||
<color name="tier_gradient_purple_start">#00000000</color>
|
||||
<color name="tier_gradient_purple_end">#E86DE3</color>
|
||||
|
||||
<color name="object_number_background">#393835</color>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -245,4 +245,6 @@
|
|||
<color name="membership_info_gradient_pink">#FFEBEB</color>
|
||||
<color name="membership_info_gradient_purple">#EBEDFE</color>
|
||||
|
||||
<color name="object_number_background">#F2F2F2</color>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -162,7 +162,7 @@
|
|||
<dimen name="viewer_grid_header_width">144dp</dimen>
|
||||
|
||||
<dimen name="viewer_base_item_list_height">40dp</dimen>
|
||||
<dimen name="dv_viewer_filter_item_height">68dp</dimen>
|
||||
<dimen name="dv_viewer_filter_item_height">72dp</dimen>
|
||||
<dimen name="db_viewer_filter_condition_item_height">48dp</dimen>
|
||||
<dimen name="default_dragger_width">48dp</dimen>
|
||||
<dimen name="default_dragger_height">4dp</dimen>
|
||||
|
|
|
@ -382,6 +382,12 @@
|
|||
<item name="android:ellipsize">end</item>
|
||||
</style>
|
||||
|
||||
<style name="ViewerFilterObjectValueStyle" parent="TextView.ContentStyle.Relations.1">
|
||||
<item name="android:textColor">@color/text_secondary</item>
|
||||
<item name="android:maxLines">1</item>
|
||||
<item name="android:ellipsize">end</item>
|
||||
</style>
|
||||
|
||||
<style name="ViewerSortTitleStyle" parent="TextView.ContentStyle.PreviewTitles.2.Medium">
|
||||
<item name="android:ellipsize">end</item>
|
||||
<item name="android:maxLines">1</item>
|
||||
|
|
|
@ -325,7 +325,7 @@
|
|||
<string name="relation_format_number">Number</string>
|
||||
<string name="relation_format_date">Date</string>
|
||||
<string name="relation_format_status">Select</string>
|
||||
<string name="relation_format_file">File</string>
|
||||
<string name="relation_format_file">File & Media</string>
|
||||
<string name="relation_format_checkbox">Checkbox</string>
|
||||
<string name="relation_format_url">Url</string>
|
||||
<string name="relation_format_email">Email</string>
|
||||
|
|
|
@ -2073,7 +2073,7 @@ class DefaultBlockViewRenderer @Inject constructor(
|
|||
val relation = storeOfRelations.getByKey(relationKey)
|
||||
if (relation != null) {
|
||||
val view = relation.view(
|
||||
details = details,
|
||||
details = details.details,
|
||||
values = details.details[ctx]?.map ?: emptyMap(),
|
||||
urlBuilder = urlBuilder
|
||||
)
|
||||
|
@ -2179,7 +2179,7 @@ class DefaultBlockViewRenderer @Inject constructor(
|
|||
else -> {
|
||||
val relation = storeOfRelations.getByKey(key)
|
||||
relation?.view(
|
||||
details = details,
|
||||
details = details.details,
|
||||
values = details.details[ctx]?.map ?: emptyMap(),
|
||||
urlBuilder = urlBuilder,
|
||||
isFeatured = true
|
||||
|
|
|
@ -45,7 +45,8 @@ fun ObjectWrapper.Relation.toConditionView(condition: DVFilterCondition?): Viewe
|
|||
}
|
||||
Relation.Format.STATUS,
|
||||
Relation.Format.TAG,
|
||||
Relation.Format.OBJECT -> {
|
||||
Relation.Format.OBJECT,
|
||||
Relation.Format.FILE -> {
|
||||
condition?.toView(category = DVFilterConditionCategory.SELECT)
|
||||
?: Viewer.Filter.Condition.Selected.selectConditions().first()
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.anytypeio.anytype.core_models.Id
|
|||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.objects.ObjectStore
|
||||
import com.anytypeio.anytype.domain.objects.StoreOfRelations
|
||||
import com.anytypeio.anytype.domain.search.DataViewState
|
||||
import com.anytypeio.anytype.presentation.relations.toView
|
||||
import com.anytypeio.anytype.presentation.sets.filter.CreateFilterView
|
||||
import com.anytypeio.anytype.presentation.sets.filter.ViewerFilterViewModel
|
||||
|
@ -60,7 +61,6 @@ fun List<CreateFilterView>.checkboxFilterValue(): Boolean? {
|
|||
suspend fun List<DVFilter>.toView(
|
||||
storeOfRelations: StoreOfRelations,
|
||||
storeOfObjects: ObjectStore,
|
||||
details: Map<Id, Block.Fields>,
|
||||
screenState: ViewerFilterViewModel.ScreenState,
|
||||
urlBuilder: UrlBuilder
|
||||
): List<FilterView.Expression> = mapNotNull { filter ->
|
||||
|
@ -68,7 +68,6 @@ suspend fun List<DVFilter>.toView(
|
|||
if (relation != null) {
|
||||
filter.toView(
|
||||
relation = relation,
|
||||
details = details,
|
||||
isInEditMode = screenState == ViewerFilterViewModel.ScreenState.EDIT,
|
||||
urlBuilder = urlBuilder,
|
||||
store = storeOfObjects
|
||||
|
|
|
@ -208,7 +208,7 @@ fun List<ObjectWrapper.Basic>.toCreateFilterObjectView(
|
|||
),
|
||||
isSelected = ids?.contains(obj.id) ?: false
|
||||
)
|
||||
}
|
||||
}.sortedByDescending { it.isSelected }
|
||||
|
||||
fun List<ObjectWrapper.Basic>.toRelationObjectValueView(
|
||||
excluded: List<Id>,
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.anytypeio.anytype.core_models.DVViewer
|
|||
import com.anytypeio.anytype.core_models.DVViewerCardSize
|
||||
import com.anytypeio.anytype.core_models.DVViewerType
|
||||
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.ext.DateParser
|
||||
|
@ -29,6 +30,7 @@ import com.anytypeio.anytype.core_utils.ext.typeOf
|
|||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.objects.ObjectStore
|
||||
import com.anytypeio.anytype.domain.objects.StoreOfRelations
|
||||
import com.anytypeio.anytype.domain.search.DataViewState
|
||||
import com.anytypeio.anytype.presentation.editor.cover.CoverImageHashProvider
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.extension.isValueRequired
|
||||
|
@ -42,6 +44,8 @@ import com.anytypeio.anytype.presentation.mapper.toTextView
|
|||
import com.anytypeio.anytype.presentation.mapper.toView
|
||||
import com.anytypeio.anytype.presentation.mapper.toViewerColumns
|
||||
import com.anytypeio.anytype.presentation.number.NumberParser
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.getProperName
|
||||
import com.anytypeio.anytype.presentation.sets.buildGalleryViews
|
||||
import com.anytypeio.anytype.presentation.sets.buildListViews
|
||||
import com.anytypeio.anytype.presentation.sets.dataViewState
|
||||
|
@ -55,7 +59,6 @@ import com.anytypeio.anytype.presentation.sets.model.TagView
|
|||
import com.anytypeio.anytype.presentation.sets.model.Viewer
|
||||
import com.anytypeio.anytype.presentation.sets.model.ViewerTabView
|
||||
import com.anytypeio.anytype.presentation.sets.state.ObjectState
|
||||
import com.anytypeio.anytype.presentation.sets.toObjectView
|
||||
import timber.log.Timber
|
||||
|
||||
fun DV.tabs(activeViewerId: String? = null): List<ViewerTabView> {
|
||||
|
@ -465,18 +468,33 @@ suspend fun ObjectWrapper.Relation.toStatus(
|
|||
}
|
||||
}
|
||||
|
||||
fun ObjectWrapper.Relation.toObjects(
|
||||
suspend fun ObjectWrapper.Relation.toObjects(
|
||||
value: Any?,
|
||||
details: Map<Id, Block.Fields>,
|
||||
store: ObjectStore,
|
||||
urlBuilder: UrlBuilder
|
||||
) : List<ObjectView> {
|
||||
val ids = value.values<Id>()
|
||||
return buildList {
|
||||
ids.forEach { id ->
|
||||
val raw = details[id]?.map
|
||||
val raw = store.get(id)?.map
|
||||
if (!raw.isNullOrEmpty()) {
|
||||
val wrapper = ObjectWrapper.Basic(raw)
|
||||
add(wrapper.toObjectView(urlBuilder))
|
||||
val obj = when (isDeleted) {
|
||||
true -> ObjectView.Deleted(id)
|
||||
else -> ObjectView.Default(
|
||||
id = id,
|
||||
name = wrapper.getProperName(),
|
||||
icon = ObjectIcon.from(
|
||||
obj = wrapper,
|
||||
layout = wrapper.layout,
|
||||
builder = urlBuilder,
|
||||
objectTypeNoIcon = false
|
||||
),
|
||||
types = type,
|
||||
isRelation = wrapper.layout == ObjectType.Layout.RELATION
|
||||
)
|
||||
}
|
||||
add(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -485,7 +503,6 @@ fun ObjectWrapper.Relation.toObjects(
|
|||
suspend fun DVFilter.toView(
|
||||
store: ObjectStore,
|
||||
relation: ObjectWrapper.Relation,
|
||||
details: Map<Id, Block.Fields>,
|
||||
isInEditMode: Boolean,
|
||||
urlBuilder: UrlBuilder
|
||||
): FilterView.Expression = when (relation.format) {
|
||||
|
@ -582,18 +599,17 @@ suspend fun DVFilter.toView(
|
|||
)
|
||||
}
|
||||
Relation.Format.STATUS -> {
|
||||
val updatedFilterValue = relation.toStatus(
|
||||
value = value,
|
||||
store = store
|
||||
)
|
||||
FilterView.Expression.Status(
|
||||
id = id,
|
||||
relation = this.relation,
|
||||
title = relation.name.orEmpty(),
|
||||
operator = operator.toView(),
|
||||
condition = condition.toSelectedView(),
|
||||
filterValue = FilterValue.Status(
|
||||
relation.toStatus(
|
||||
value = value,
|
||||
store = store
|
||||
)
|
||||
),
|
||||
filterValue = FilterValue.Status(value = updatedFilterValue),
|
||||
format = relation.format.toView(),
|
||||
isValueRequired = condition.isValueRequired(),
|
||||
isInEditMode = isInEditMode
|
||||
|
@ -617,14 +633,20 @@ suspend fun DVFilter.toView(
|
|||
isInEditMode = isInEditMode
|
||||
)
|
||||
}
|
||||
Relation.Format.OBJECT -> {
|
||||
Relation.Format.OBJECT, Relation.Format.FILE -> {
|
||||
FilterView.Expression.Object(
|
||||
id = id,
|
||||
relation = this.relation,
|
||||
title = relation.name.orEmpty(),
|
||||
operator = operator.toView(),
|
||||
condition = condition.toSelectedView(),
|
||||
filterValue = FilterValue.Object(relation.toObjects(value, details, urlBuilder)),
|
||||
filterValue = FilterValue.Object(
|
||||
relation.toObjects(
|
||||
value = value,
|
||||
store = store,
|
||||
urlBuilder = urlBuilder
|
||||
)
|
||||
),
|
||||
format = relation.format.toView(),
|
||||
isValueRequired = condition.isValueRequired(),
|
||||
isInEditMode = isInEditMode
|
||||
|
@ -671,7 +693,14 @@ suspend fun ObjectWrapper.Relation.toFilterValue(
|
|||
Relation.Format.URL -> FilterValue.Url(toText(value))
|
||||
Relation.Format.EMAIL -> FilterValue.Email(toText(value))
|
||||
Relation.Format.PHONE -> FilterValue.Phone(toText(value))
|
||||
Relation.Format.OBJECT -> FilterValue.Object(toObjects(value, details, urlBuilder))
|
||||
Relation.Format.OBJECT, Relation.Format.FILE -> {
|
||||
val obj = toObjects(
|
||||
value = value,
|
||||
store = store,
|
||||
urlBuilder = urlBuilder
|
||||
)
|
||||
FilterValue.Object(obj)
|
||||
}
|
||||
Relation.Format.CHECKBOX -> FilterValue.Check(toCheckbox(value))
|
||||
else -> throw UnsupportedOperationException("Unsupported relation format:${format}")
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ fun List<ObjectWrapper.Relation>.views(
|
|||
featured: List<Id> = emptyList()
|
||||
): List<ObjectRelationView> = mapNotNull { relation ->
|
||||
relation.view(
|
||||
details = details,
|
||||
details = details.details,
|
||||
values = values,
|
||||
urlBuilder = urlBuilder,
|
||||
isFeatured = featured.contains(relation.key)
|
||||
|
@ -33,7 +33,7 @@ fun List<ObjectWrapper.Relation>.views(
|
|||
fun Key.isSystemKey() : Boolean = Relations.systemRelationKeys.contains(this)
|
||||
|
||||
fun ObjectWrapper.Relation.view(
|
||||
details: Block.Details,
|
||||
details: Map<Id, Block.Fields>,
|
||||
values: Map<String, Any?>,
|
||||
urlBuilder: UrlBuilder,
|
||||
isFeatured: Boolean = false
|
||||
|
@ -43,7 +43,7 @@ fun ObjectWrapper.Relation.view(
|
|||
RelationFormat.OBJECT -> {
|
||||
val objects = values.buildRelationValueObjectViews(
|
||||
relationKey = relation.key,
|
||||
details = details.details,
|
||||
details = details,
|
||||
builder = urlBuilder
|
||||
)
|
||||
ObjectRelationView.Object(
|
||||
|
@ -59,7 +59,7 @@ fun ObjectWrapper.Relation.view(
|
|||
RelationFormat.FILE -> {
|
||||
val files = values.buildFileViews(
|
||||
relationKey = relation.key,
|
||||
details = details.details
|
||||
details = details
|
||||
)
|
||||
ObjectRelationView.File(
|
||||
id = relation.id,
|
||||
|
@ -99,7 +99,7 @@ fun ObjectWrapper.Relation.view(
|
|||
val options = buildList {
|
||||
when(val value = values[relation.key]) {
|
||||
is Id -> {
|
||||
val status = details.details[value]
|
||||
val status = details[value]
|
||||
if (status != null && status.map.isNotEmpty()) {
|
||||
add(
|
||||
ObjectWrapper.Option(status.map)
|
||||
|
@ -108,7 +108,7 @@ fun ObjectWrapper.Relation.view(
|
|||
}
|
||||
is List<*> -> {
|
||||
value.forEach { id ->
|
||||
val status = details.details[id]
|
||||
val status = details[id]
|
||||
if (status != null && status.map.isNotEmpty()) {
|
||||
add(
|
||||
ObjectWrapper.Option(status.map)
|
||||
|
@ -136,7 +136,7 @@ fun ObjectWrapper.Relation.view(
|
|||
val options = buildList {
|
||||
when(val value = values[relation.key]) {
|
||||
is Id -> {
|
||||
val status = details.details[value]
|
||||
val status = details[value]
|
||||
if (status != null && status.map.isNotEmpty()) {
|
||||
add(
|
||||
ObjectWrapper.Option(status.map)
|
||||
|
@ -145,7 +145,7 @@ fun ObjectWrapper.Relation.view(
|
|||
}
|
||||
is List<*> -> {
|
||||
value.forEach { id ->
|
||||
val status = details.details[id]
|
||||
val status = details[id]
|
||||
if (status != null && status.map.isNotEmpty()) {
|
||||
add(
|
||||
ObjectWrapper.Option(status.map)
|
||||
|
|
|
@ -290,6 +290,44 @@ object ObjectSearchConstants {
|
|||
}
|
||||
}
|
||||
|
||||
fun filterAddObjectToFilterByLayout(space: Id, layouts: List<ObjectType.Layout>) = buildList {
|
||||
add(
|
||||
DVFilter(
|
||||
relation = Relations.IS_ARCHIVED,
|
||||
condition = DVFilterCondition.NOT_EQUAL,
|
||||
value = true
|
||||
)
|
||||
)
|
||||
add(
|
||||
DVFilter(
|
||||
relation = Relations.IS_HIDDEN,
|
||||
condition = DVFilterCondition.NOT_EQUAL,
|
||||
value = true
|
||||
)
|
||||
)
|
||||
add(
|
||||
DVFilter(
|
||||
relation = Relations.IS_DELETED,
|
||||
condition = DVFilterCondition.NOT_EQUAL,
|
||||
value = true
|
||||
)
|
||||
)
|
||||
add(
|
||||
DVFilter(
|
||||
relation = Relations.SPACE_ID,
|
||||
condition = DVFilterCondition.EQUAL,
|
||||
value = space
|
||||
)
|
||||
)
|
||||
add(
|
||||
DVFilter(
|
||||
relation = Relations.LAYOUT,
|
||||
condition = DVFilterCondition.IN,
|
||||
value = layouts.map { it.code.toDouble() }
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val sortAddObjectToFilter = listOf(
|
||||
DVSort(
|
||||
relationKey = Relations.NAME,
|
||||
|
|
|
@ -199,7 +199,7 @@ private fun ObjectState.DataView.mapFeaturedRelations(
|
|||
else -> {
|
||||
val relation = relations.firstOrNull { it.key == key }
|
||||
relation?.view(
|
||||
details = details,
|
||||
details = details.details,
|
||||
values = details.details[ctx]?.map ?: emptyMap(),
|
||||
urlBuilder = urlBuilder,
|
||||
isFeatured = true
|
||||
|
|
|
@ -34,7 +34,7 @@ abstract class SearchRelationViewModel(
|
|||
private val notAllowedRelationFormats = listOf(
|
||||
ColumnView.Format.RELATIONS,
|
||||
ColumnView.Format.EMOJI,
|
||||
ColumnView.Format.FILE
|
||||
ColumnView.Format.UNDEFINED
|
||||
)
|
||||
private val jobs = mutableListOf<Job>()
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModelProvider
|
|||
import com.anytypeio.anytype.domain.objects.StoreOfRelations
|
||||
import com.anytypeio.anytype.presentation.sets.state.ObjectState
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import timber.log.Timber
|
||||
|
||||
class SelectFilterRelationViewModel(
|
||||
private val objectState: StateFlow<ObjectState>,
|
||||
|
@ -14,6 +15,10 @@ class SelectFilterRelationViewModel(
|
|||
storeOfRelations = storeOfRelations
|
||||
) {
|
||||
|
||||
init {
|
||||
Timber.d("SelectFilterRelationViewModel, init")
|
||||
}
|
||||
|
||||
class Factory(
|
||||
private val objectState: StateFlow<ObjectState>,
|
||||
private val storeOfRelations: StoreOfRelations
|
||||
|
|
|
@ -4,12 +4,14 @@ import com.anytypeio.anytype.core_models.Id
|
|||
import com.anytypeio.anytype.presentation.common.BaseViewModel
|
||||
import com.anytypeio.anytype.presentation.sets.model.ColumnView.Format
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import timber.log.Timber
|
||||
|
||||
class CreateFilterFlowViewModel : BaseViewModel() {
|
||||
|
||||
val step = MutableStateFlow<Step>(Step.SelectRelation)
|
||||
|
||||
fun onRelationSelected(ctx: Id, relation: Id, format: Format) {
|
||||
Timber.d("onRelationSelected: ctx=$ctx, relation=$relation, format=$format")
|
||||
step.value = Step.CreateFilter(
|
||||
ctx = ctx,
|
||||
relation = relation,
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.anytypeio.anytype.core_models.DVFilterQuickOption
|
|||
import com.anytypeio.anytype.core_models.DVViewer
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Key
|
||||
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
|
||||
|
@ -33,6 +34,7 @@ import com.anytypeio.anytype.presentation.extension.logEvent
|
|||
import com.anytypeio.anytype.presentation.extension.toConditionView
|
||||
import com.anytypeio.anytype.presentation.extension.type
|
||||
import com.anytypeio.anytype.presentation.mapper.toDomain
|
||||
import com.anytypeio.anytype.presentation.objects.SupportedLayouts
|
||||
import com.anytypeio.anytype.presentation.objects.toCreateFilterObjectView
|
||||
import com.anytypeio.anytype.presentation.relations.FilterInputValueParser
|
||||
import com.anytypeio.anytype.presentation.relations.toCreateFilterCheckboxView
|
||||
|
@ -298,6 +300,14 @@ open class FilterViewModel(
|
|||
limitObjectTypes = limitObjectTypes
|
||||
)
|
||||
}
|
||||
Relation.Format.FILE -> {
|
||||
val ids = filter?.value as? List<*>
|
||||
proceedWithSearchObjectsByLayout(
|
||||
ids = ids,
|
||||
objectTypes = storeOfObjectTypes.getAll(),
|
||||
layouts = SupportedLayouts.fileLayouts
|
||||
)
|
||||
}
|
||||
Relation.Format.CHECKBOX -> {
|
||||
filterValueListState.value =
|
||||
relation.toCreateFilterCheckboxView(filter?.value as? Boolean)
|
||||
|
@ -396,6 +406,39 @@ open class FilterViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
private fun proceedWithSearchObjectsByLayout(
|
||||
ids: List<*>? = null,
|
||||
layouts: List<ObjectType.Layout>,
|
||||
objectTypes: List<ObjectWrapper.Type>
|
||||
) {
|
||||
Timber.d("proceedWithSearchObjectsByLayout, layouts:[$layouts], objectTypes:[$objectTypes]")
|
||||
viewModelScope.launch {
|
||||
searchObjects(
|
||||
SearchObjects.Params(
|
||||
sorts = ObjectSearchConstants.sortAddObjectToFilter,
|
||||
filters = ObjectSearchConstants.filterAddObjectToFilterByLayout(
|
||||
layouts = layouts,
|
||||
space = spaceManager.get()
|
||||
),
|
||||
fulltext = SearchObjects.EMPTY_TEXT,
|
||||
offset = SearchObjects.INIT_OFFSET,
|
||||
limit = SearchObjects.LIMIT
|
||||
)
|
||||
).process(
|
||||
failure = { Timber.e(it, "Error while getting objects") },
|
||||
success = { objects ->
|
||||
filterValueListState.value = objects.toCreateFilterObjectView(
|
||||
ids = ids,
|
||||
urlBuilder = urlBuilder,
|
||||
objectTypes = objectTypes
|
||||
).also {
|
||||
optionCountState.value = it.count { view -> view.isSelected }
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun onConditionClicked() {
|
||||
val condition = conditionState.value?.condition
|
||||
checkNotNull(condition)
|
||||
|
@ -564,7 +607,7 @@ open class FilterViewModel(
|
|||
condition = condition.toDomain()
|
||||
)
|
||||
}
|
||||
ColumnView.Format.OBJECT -> {
|
||||
ColumnView.Format.OBJECT, ColumnView.Format.FILE -> {
|
||||
val objects =
|
||||
filterValueListState.value.filterIsInstance<CreateFilterView.Object>()
|
||||
val selected = objects
|
||||
|
@ -707,7 +750,7 @@ open class FilterViewModel(
|
|||
)
|
||||
)
|
||||
}
|
||||
ColumnView.Format.OBJECT -> {
|
||||
ColumnView.Format.OBJECT, ColumnView.Format.FILE -> {
|
||||
val value = filterValueListState.value.mapNotNull { view ->
|
||||
if (view is CreateFilterView.Object && view.isSelected)
|
||||
view.id
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.anytypeio.anytype.domain.base.fold
|
|||
import com.anytypeio.anytype.domain.dataview.interactor.UpdateDataViewViewer
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.objects.StoreOfRelations
|
||||
import com.anytypeio.anytype.domain.search.DataViewState
|
||||
import com.anytypeio.anytype.presentation.common.BaseListViewModel
|
||||
import com.anytypeio.anytype.presentation.extension.ObjectStateAnalyticsEvent
|
||||
import com.anytypeio.anytype.presentation.extension.logEvent
|
||||
|
@ -45,25 +46,29 @@ class ViewerFilterViewModel(
|
|||
fun onStart(viewerId: Id) {
|
||||
Timber.d("ViewerFilterViewModel, onStart, viewerId: [$viewerId]")
|
||||
jobs += viewModelScope.launch {
|
||||
objectState.filterIsInstance<ObjectState.DataView>().collect { objectSet ->
|
||||
val filterExpression = objectSet.filterExpression(viewerId = viewerId)
|
||||
if (filterExpression.isEmpty()) {
|
||||
screenState.value = ScreenState.EMPTY
|
||||
} else {
|
||||
screenState.value = when (screenState.value) {
|
||||
ScreenState.LIST -> ScreenState.LIST
|
||||
ScreenState.EDIT -> ScreenState.EDIT
|
||||
ScreenState.EMPTY -> ScreenState.LIST
|
||||
db.index.filterIsInstance<DataViewState.Loaded>()
|
||||
.combine(
|
||||
objectState.filterIsInstance<ObjectState.DataView>()
|
||||
) { _, objectSet ->
|
||||
objectSet
|
||||
}.collect { objectSet ->
|
||||
val filterExpression = objectSet.filterExpression(viewerId = viewerId)
|
||||
if (filterExpression.isEmpty()) {
|
||||
screenState.value = ScreenState.EMPTY
|
||||
} else {
|
||||
screenState.value = when (screenState.value) {
|
||||
ScreenState.LIST -> ScreenState.LIST
|
||||
ScreenState.EDIT -> ScreenState.EDIT
|
||||
ScreenState.EMPTY -> ScreenState.LIST
|
||||
}
|
||||
}
|
||||
_views.value = filterExpression.toView(
|
||||
storeOfRelations = storeOfRelations,
|
||||
storeOfObjects = db.store,
|
||||
screenState = screenState.value,
|
||||
urlBuilder = urlBuilder
|
||||
)
|
||||
}
|
||||
_views.value = filterExpression.toView(
|
||||
storeOfRelations = storeOfRelations,
|
||||
storeOfObjects = db.store,
|
||||
details = objectSet.details,
|
||||
screenState = screenState.value,
|
||||
urlBuilder = urlBuilder
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue