Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#539 PrettyTime Missing Unit Workaround #687

Merged
merged 2 commits into from
Jun 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions app/src/main/java/com/jerboa/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ import java.util.*
import kotlin.math.abs
import kotlin.math.pow

val prettyTime = PrettyTime(Locale.getDefault())

val gson = Gson()

const val DEBOUNCE_DELAY = 1000L
Expand Down Expand Up @@ -394,6 +392,28 @@ fun openLink(url: String, navController: NavController, useCustomTab: Boolean, u
}
}

var prettyTime = PrettyTime(Locale.getDefault())
var prettyTimeEnglish = PrettyTime(Locale.ENGLISH)
val invalidPrettyDateRegex = "^[0123456789 ]+$".toRegex()
fun formatDuration(date: Date, longTimeFormat: Boolean = false): String {
if (prettyTime.locale != Locale.getDefault()) {
prettyTime = PrettyTime(Locale.getDefault())
}

var prettyDate = prettyTime.formatDuration(date)

// A bug in PrettyTime means that some languages (pl, ru, uk, kk) will not include any time unit
if (prettyDate.matches(invalidPrettyDateRegex)) {
Copy link
Member

@dessalines dessalines Jun 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where's the bug in prettytime? It seems pretty active. Definitely open up a PR over there, and reference it here, so that we don't always have to use this hack.

Copy link
Contributor Author

@lbenedetto lbenedetto Jun 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I linked the pretty time bug report in the PR description.

But really, it's not so much a bug as a lack of support for these languages. For other languages, they have maps of words in those languages and logic to choose those words with the correct plurality and such.

However, for these four languages, the implementation does not contain any words or logic and just returns back whatever number was passed in.

So I don't think this is a quick fix for them.

I wrote this workaround here so that if/when the issue is fixed, it won't continue defaulting to English, it'll just become irrelevant.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmmk, thanks!

prettyDate = prettyTimeEnglish.formatDuration(date)
}

return if (longTimeFormat) {
prettyDate
} else {
prettyTimeShortener(prettyDate)
}
}

fun prettyTimeShortener(timeString: String): String {
return if (prettyTime.locale.language == "en") {
if (timeString.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ fun Sidebar(
}
TimeAgo(
precedingString = stringResource(R.string.AppBars_created),
includeAgo = true,
longTimeFormat = true,
published = published,
)
CommentsAndPosts(
Expand Down
19 changes: 6 additions & 13 deletions app/src/main/java/com/jerboa/ui/components/common/TimeAgo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ import androidx.compose.ui.unit.dp
import com.jerboa.R
import com.jerboa.datatypes.samplePerson
import com.jerboa.datatypes.samplePost
import com.jerboa.prettyTime
import com.jerboa.prettyTimeShortener
import com.jerboa.formatDuration
import com.jerboa.ui.theme.SMALL_PADDING
import com.jerboa.ui.theme.muted
import java.time.Instant
Expand All @@ -37,9 +36,9 @@ fun TimeAgo(
published: String,
updated: String? = null,
precedingString: String? = null,
includeAgo: Boolean = false,
longTimeFormat: Boolean = false,
) {
val publishedPretty = dateStringToPretty(published, includeAgo)
val publishedPretty = dateStringToPretty(published, longTimeFormat)

val afterPreceding = precedingString?.let {
stringResource(R.string.time_ago_ago, it, publishedPretty)
Expand All @@ -53,7 +52,7 @@ fun TimeAgo(
)

updated?.also {
val updatedPretty = dateStringToPretty(it, includeAgo)
val updatedPretty = dateStringToPretty(it, longTimeFormat)

DotSpacer(
padding = SMALL_PADDING,
Expand All @@ -69,15 +68,9 @@ fun TimeAgo(
}
}

fun dateStringToPretty(dateStr: String, includeAgo: Boolean = false): String {
fun dateStringToPretty(dateStr: String, longTimeFormat: Boolean = false): String {
val publishedDate = Date.from(Instant.parse(dateStr + "Z"))
val prettyPublished = prettyTime.formatDuration(publishedDate)

return if (includeAgo) {
prettyPublished
} else {
prettyTimeShortener(prettyPublished)
}
return formatDuration(publishedDate, longTimeFormat)
}

@Preview
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ fun PersonProfileTopSection(

TimeAgo(
precedingString = stringResource(R.string.person_profile_joined),
includeAgo = true,
longTimeFormat = true,
published = personView.person.published,
)
CommentsAndPosts(personView)
Expand Down
25 changes: 25 additions & 0 deletions app/src/test/java/com/jerboa/UtilsKtTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import com.jerboa.api.API
import com.jerboa.ui.theme.SMALL_PADDING
import org.junit.Assert.*
import org.junit.Test
import org.ocpsoft.prettytime.PrettyTime
import java.time.Duration
import java.time.Instant
import java.util.Date
import java.util.Locale

class UtilsKtTest {
@Test
Expand Down Expand Up @@ -147,4 +152,24 @@ class UtilsKtTest {

cases.forEach { (url, exp) -> assertEquals(exp, parseUrl(url)) }
}

@Test
fun testBrokenLanguagesRemappedToEnglish() {
listOf("pl", "ru", "uk", "kk").forEach { locale ->
val date = Date.from(Instant.now().minus(Duration.ofDays(1)))
prettyTime = PrettyTime(Locale(locale))

val durationString = formatDuration(date, true)
assertNotEquals("1", durationString)
}
}

@Test
fun testEnglish() {
val date = Date.from(Instant.now().minus(Duration.ofDays(1)))
Locale.setDefault(Locale.ENGLISH)

val durationString = formatDuration(date, true)
assertEquals("1 day", durationString)
}
}