1
0
Fork 0
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:
Sergey Boishtyan 2022-05-11 20:06:23 +03:00 committed by GitHub
parent a52a25a1e2
commit a6b2da18f9
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 156 additions and 70 deletions

View file

@ -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

View file

@ -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)
}
}

View file

@ -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
}

View file

@ -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
}
}

View file

@ -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

View file

@ -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> {

View file

@ -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]

View file

@ -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

View file

@ -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?>,

View file

@ -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

View file

@ -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))
}
}