mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
Relation | Fix | incorrect number presentation (#2254)
This commit is contained in:
parent
a52a25a1e2
commit
a6b2da18f9
11 changed files with 156 additions and 70 deletions
|
@ -24,7 +24,7 @@ import com.anytypeio.anytype.emojifier.data.DefaultDocumentEmojiIconProvider
|
|||
import com.anytypeio.anytype.features.editor.base.EditorTestSetup
|
||||
import com.anytypeio.anytype.features.editor.base.TestEditorFragment
|
||||
import com.anytypeio.anytype.presentation.editor.EditorViewModel
|
||||
import com.anytypeio.anytype.presentation.relations.NumberParser
|
||||
import com.anytypeio.anytype.presentation.number.NumberParser
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
import com.anytypeio.anytype.test_utils.utils.checkHasText
|
||||
import com.anytypeio.anytype.test_utils.utils.checkIsDisplayed
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
package com.anytypeio.anytype.core_ui
|
||||
|
||||
import com.anytypeio.anytype.core_utils.ext.firstDigitByHash
|
||||
import com.anytypeio.anytype.core_utils.ext.isWhole
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class ExtensionsTest {
|
||||
|
||||
|
@ -28,31 +25,4 @@ class ExtensionsTest {
|
|||
|
||||
assertEquals(expected = 0, actual = result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should be whole double`() {
|
||||
val d = 654.0
|
||||
|
||||
val result = d.isWhole()
|
||||
|
||||
assertTrue(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should not be negative whole double`() {
|
||||
val d = -555.0
|
||||
|
||||
val result = d.isWhole()
|
||||
|
||||
assertTrue(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should not be whole double`() {
|
||||
val d = 654.1
|
||||
|
||||
val result = d.isWhole()
|
||||
|
||||
assertFalse(result)
|
||||
}
|
||||
}
|
|
@ -75,6 +75,4 @@ fun String.isEndLineClick(range: IntRange): Boolean = range.first == length && r
|
|||
inline fun <reified T> Fragment.withParent(action: T.() -> Unit) {
|
||||
check(parentFragment is T) { "Parent is not ${T::class.java}. Please specify correct type" }
|
||||
(parentFragment as T).action()
|
||||
}
|
||||
|
||||
fun Double.isWhole(): Boolean = this - this.toInt() == 0.0
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.anytypeio.anytype.presentation.number
|
||||
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
|
||||
/**
|
||||
* Converts relation {format NUMBER} value {Any?} to string representation or null
|
||||
*/
|
||||
object NumberParser {
|
||||
|
||||
fun parse(value: Any?): String? {
|
||||
val doubleValue = when (value) {
|
||||
is String -> value.toDouble()
|
||||
is Number -> value.toDouble()
|
||||
else -> null
|
||||
}
|
||||
return if (doubleValue != null) {
|
||||
val decimal = BigDecimal.valueOf(doubleValue)
|
||||
if (decimal.isWhole) {
|
||||
decimal.longValueExact().toString()
|
||||
} else {
|
||||
decimal.toPlainString()
|
||||
}
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private val BigDecimal.isWhole: Boolean
|
||||
get() {
|
||||
// fast-path
|
||||
if(scale() <= 0) return true
|
||||
val digitsAfterDot = this - this.setScale(0, RoundingMode.DOWN)
|
||||
// [BigDecimal.equals] check `scale` and other properties
|
||||
return digitsAfterDot.compareTo(BigDecimal.ZERO) == 0
|
||||
}
|
||||
}
|
|
@ -1,11 +1,15 @@
|
|||
package com.anytypeio.anytype.presentation.objects
|
||||
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.DVViewerRelation
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Relation
|
||||
import com.anytypeio.anytype.core_utils.const.DateConst
|
||||
import com.anytypeio.anytype.core_utils.ext.typeOf
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.number.NumberParser
|
||||
import com.anytypeio.anytype.presentation.relations.DateParser
|
||||
import com.anytypeio.anytype.presentation.relations.NumberParser
|
||||
import com.anytypeio.anytype.presentation.relations.model.DefaultObjectRelationValueView
|
||||
import com.anytypeio.anytype.presentation.sets.model.FileView
|
||||
import com.anytypeio.anytype.presentation.sets.model.ObjectView
|
||||
|
|
|
@ -1,14 +1,49 @@
|
|||
package com.anytypeio.anytype.presentation.relations
|
||||
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.CoverType
|
||||
import com.anytypeio.anytype.core_models.DV
|
||||
import com.anytypeio.anytype.core_models.DVFilter
|
||||
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.Url
|
||||
import com.anytypeio.anytype.core_models.ext.content
|
||||
import com.anytypeio.anytype.core_models.ext.title
|
||||
import com.anytypeio.anytype.core_utils.ext.*
|
||||
import com.anytypeio.anytype.core_utils.ext.EMPTY_TIMESTAMP
|
||||
import com.anytypeio.anytype.core_utils.ext.EXACT_DAY
|
||||
import com.anytypeio.anytype.core_utils.ext.MONTH_AGO
|
||||
import com.anytypeio.anytype.core_utils.ext.MONTH_AHEAD
|
||||
import com.anytypeio.anytype.core_utils.ext.TODAY
|
||||
import com.anytypeio.anytype.core_utils.ext.TOMORROW
|
||||
import com.anytypeio.anytype.core_utils.ext.WEEK_AGO
|
||||
import com.anytypeio.anytype.core_utils.ext.WEEK_AHEAD
|
||||
import com.anytypeio.anytype.core_utils.ext.YESTERDAY
|
||||
import com.anytypeio.anytype.core_utils.ext.getMonthAgoTimeUnit
|
||||
import com.anytypeio.anytype.core_utils.ext.getMonthAheadTimeUnit
|
||||
import com.anytypeio.anytype.core_utils.ext.getTodayTimeUnit
|
||||
import com.anytypeio.anytype.core_utils.ext.getTomorrowTimeUnit
|
||||
import com.anytypeio.anytype.core_utils.ext.getWeekAgoTimeUnit
|
||||
import com.anytypeio.anytype.core_utils.ext.getWeekAheadTimeUnit
|
||||
import com.anytypeio.anytype.core_utils.ext.getYesterdayTimeUnit
|
||||
import com.anytypeio.anytype.core_utils.ext.isSameDay
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.editor.cover.CoverColor
|
||||
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
|
||||
import com.anytypeio.anytype.presentation.extension.isValueRequired
|
||||
import com.anytypeio.anytype.presentation.mapper.*
|
||||
import com.anytypeio.anytype.presentation.mapper.toCheckboxView
|
||||
import com.anytypeio.anytype.presentation.mapper.toGridRecordRows
|
||||
import com.anytypeio.anytype.presentation.mapper.toNumberView
|
||||
import com.anytypeio.anytype.presentation.mapper.toSelectedView
|
||||
import com.anytypeio.anytype.presentation.mapper.toSimpleRelations
|
||||
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.ObjectSet
|
||||
|
@ -16,10 +51,18 @@ import com.anytypeio.anytype.presentation.sets.ObjectSetViewState
|
|||
import com.anytypeio.anytype.presentation.sets.buildGalleryViews
|
||||
import com.anytypeio.anytype.presentation.sets.buildListViews
|
||||
import com.anytypeio.anytype.presentation.sets.filter.CreateFilterView
|
||||
import com.anytypeio.anytype.presentation.sets.model.*
|
||||
import com.anytypeio.anytype.presentation.sets.model.ColumnView
|
||||
import com.anytypeio.anytype.presentation.sets.model.FilterValue
|
||||
import com.anytypeio.anytype.presentation.sets.model.FilterView
|
||||
import com.anytypeio.anytype.presentation.sets.model.ObjectView
|
||||
import com.anytypeio.anytype.presentation.sets.model.SimpleRelationView
|
||||
import com.anytypeio.anytype.presentation.sets.model.SortingExpression
|
||||
import com.anytypeio.anytype.presentation.sets.model.StatusView
|
||||
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 timber.log.Timber
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
|
||||
fun ObjectSet.tabs(activeViewerId: String? = null): List<ViewerTabView> {
|
||||
|
|
|
@ -3,9 +3,9 @@ package com.anytypeio.anytype.presentation.relations
|
|||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.core_models.Relations.NUMBER_DEFAULT_VALUE
|
||||
import com.anytypeio.anytype.core_utils.const.DateConst
|
||||
import com.anytypeio.anytype.core_utils.ext.isWhole
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.extension.hasValue
|
||||
import com.anytypeio.anytype.presentation.number.NumberParser
|
||||
import com.anytypeio.anytype.presentation.relations.model.RelationView
|
||||
import com.anytypeio.anytype.presentation.sets.*
|
||||
import com.anytypeio.anytype.presentation.sets.model.ColumnView
|
||||
|
@ -33,7 +33,7 @@ fun Relation.view(
|
|||
values: Map<String, Any?>,
|
||||
urlBuilder: UrlBuilder,
|
||||
isFeatured: Boolean = false
|
||||
) : DocumentRelationView? {
|
||||
): DocumentRelationView? {
|
||||
val relation = this
|
||||
return when {
|
||||
relation.isHidden -> null
|
||||
|
@ -198,28 +198,6 @@ object DateParser {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts relation {format NUMBER} value {Any?} to string representation or null
|
||||
*/
|
||||
object NumberParser {
|
||||
fun parse(value: Any?): String? = when (value) {
|
||||
is String -> {
|
||||
val num = value.toDoubleOrNull()
|
||||
num?.convertToString()
|
||||
}
|
||||
is Number -> {
|
||||
val num = value.toDouble()
|
||||
num.convertToString()
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun Double.convertToString(): String = if (isWhole())
|
||||
this.toLong().toString()
|
||||
else
|
||||
this.toString()
|
||||
|
||||
/**
|
||||
* Get date format for ColumnView type DATE
|
||||
* @tests [SetsExtensionTests]
|
||||
|
|
|
@ -6,7 +6,7 @@ import androidx.lifecycle.viewModelScope
|
|||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Relation
|
||||
import com.anytypeio.anytype.core_utils.ext.cancel
|
||||
import com.anytypeio.anytype.presentation.relations.NumberParser
|
||||
import com.anytypeio.anytype.presentation.number.NumberParser
|
||||
import com.anytypeio.anytype.presentation.relations.providers.ObjectRelationProvider
|
||||
import com.anytypeio.anytype.presentation.relations.providers.ObjectValueProvider
|
||||
import kotlinx.coroutines.Job
|
||||
|
|
|
@ -1,15 +1,26 @@
|
|||
package com.anytypeio.anytype.presentation.sets
|
||||
|
||||
import com.anytypeio.anytype.core_models.*
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
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_utils.ext.typeOf
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
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.relations.DateParser
|
||||
import com.anytypeio.anytype.presentation.relations.NumberParser
|
||||
import com.anytypeio.anytype.presentation.relations.ObjectSetConfig
|
||||
import com.anytypeio.anytype.presentation.relations.getDateRelationFormat
|
||||
import com.anytypeio.anytype.presentation.sets.model.*
|
||||
import com.anytypeio.anytype.presentation.sets.model.CellView
|
||||
import com.anytypeio.anytype.presentation.sets.model.ColumnView
|
||||
import com.anytypeio.anytype.presentation.sets.model.FileView
|
||||
import com.anytypeio.anytype.presentation.sets.model.ObjectView
|
||||
import com.anytypeio.anytype.presentation.sets.model.StatusView
|
||||
import com.anytypeio.anytype.presentation.sets.model.TagView
|
||||
import com.anytypeio.anytype.presentation.sets.model.Viewer
|
||||
|
||||
fun List<ColumnView>.buildGridRow(
|
||||
record: Map<String, Any?>,
|
||||
|
|
|
@ -11,8 +11,8 @@ import com.anytypeio.anytype.presentation.editor.editor.slash.SlashEvent
|
|||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashItem
|
||||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashRelationView
|
||||
import com.anytypeio.anytype.presentation.editor.editor.slash.SlashWidgetState
|
||||
import com.anytypeio.anytype.presentation.number.NumberParser
|
||||
import com.anytypeio.anytype.presentation.relations.DocumentRelationView
|
||||
import com.anytypeio.anytype.presentation.relations.NumberParser
|
||||
import com.anytypeio.anytype.presentation.util.CoroutinesTestRule
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
import org.junit.Before
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package com.anytypeio.anytype.presentation.relations
|
||||
|
||||
import com.anytypeio.anytype.presentation.number.NumberParser
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class NumberParserTest {
|
||||
|
||||
@Test
|
||||
fun `whole number - shown without point`() {
|
||||
assertEquals("1", NumberParser.parse("1.00"))
|
||||
assertEquals("1", NumberParser.parse(1.00))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `two digits after dot - shown with two digits after dot`() {
|
||||
assertEquals("1.11", NumberParser.parse("1.11"))
|
||||
assertEquals("1.11", NumberParser.parse(1.11))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `two digits after dot with zero at the end - shown as one digit after dot`() {
|
||||
assertEquals("1.1", NumberParser.parse("1.10"))
|
||||
assertEquals("1.1", NumberParser.parse(1.10))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `big number whole number`() {
|
||||
assertEquals("3757556070", NumberParser.parse("3757556070"))
|
||||
assertEquals("3757556070", NumberParser.parse(3757556070))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `big number real number`() {
|
||||
assertEquals("3757556070.1", NumberParser.parse("3757556070.1"))
|
||||
assertEquals("3757556070.1", NumberParser.parse(3757556070.1))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `many digits after dot`() {
|
||||
assertEquals("1.11111111111115", NumberParser.parse("1.11111111111115"))
|
||||
assertEquals("1.11111111111115", NumberParser.parse(1.11111111111115))
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue