Skip to content

Commit

Permalink
feat: relative dates
Browse files Browse the repository at this point in the history
  • Loading branch information
PavloNetrebchuk committed Jul 18, 2024
1 parent 559c7e4 commit f001577
Show file tree
Hide file tree
Showing 32 changed files with 231 additions and 205 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@ class PreferencesManager(context: Context) : CorePreferences, ProfilePreferences
}
get() = getString(CALENDAR_USER)

override var isRelativeDateEnabled: Boolean
set(value) {
saveBoolean(IS_RELATIVE_DATES_ENABLED, value)
}
get() = getBoolean(IS_RELATIVE_DATES_ENABLED, true)

override var isHideInactiveCourses: Boolean
set(value) {
saveBoolean(HIDE_INACTIVE_COURSES, value)
Expand Down Expand Up @@ -223,6 +229,7 @@ class PreferencesManager(context: Context) : CorePreferences, ProfilePreferences
private const val CALENDAR_ID = "CALENDAR_ID"
private const val RESET_APP_DIRECTORY = "reset_app_directory"
private const val IS_CALENDAR_SYNC_ENABLED = "IS_CALENDAR_SYNC_ENABLED"
private const val IS_RELATIVE_DATES_ENABLED = "IS_RELATIVE_DATES_ENABLED"
private const val HIDE_INACTIVE_COURSES = "HIDE_INACTIVE_COURSES"
private const val CALENDAR_USER = "CALENDAR_USER"
}
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/java/org/openedx/app/di/ScreenModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ val screenModule = module {
get(),
get(),
get(),
get(),
windowSize
)
}
Expand Down Expand Up @@ -202,7 +203,7 @@ val screenModule = module {
)
}
viewModel { ManageAccountViewModel(get(), get(), get(), get(), get()) }
viewModel { CalendarViewModel(get(), get(), get(), get(), get(), get(), get()) }
viewModel { CalendarViewModel(get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel { CoursesToSyncViewModel(get(), get(), get(), get()) }
viewModel { NewCalendarDialogViewModel(get(), get(), get(), get(), get(), get()) }
viewModel { DisableCalendarSyncDialogViewModel(get(), get(), get(), get()) }
Expand Down Expand Up @@ -271,7 +272,7 @@ val screenModule = module {
get(),
get(),
get(),
get()
get(),
)
}
viewModel { (courseId: String) ->
Expand Down Expand Up @@ -354,6 +355,7 @@ val screenModule = module {
get(),
get(),
get(),
get(),
)
}
viewModel { (courseId: String, handoutsType: String) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface CorePreferences {
var videoSettings: VideoSettings
var appConfig: AppConfig
var canResetAppDirectory: Boolean
var isRelativeDateEnabled: Boolean

fun clearCorePreferences()
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package org.openedx.core.domain.model
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import org.openedx.core.data.model.DateType
import org.openedx.core.utils.isTimeLessThan24Hours
import org.openedx.core.utils.isToday
import java.util.Date

@Parcelize
Expand All @@ -29,10 +27,6 @@ data class CourseDateBlock(
) && date.before(Date()))
}

fun isTimeDifferenceLessThan24Hours(): Boolean {
return (date.isToday() && date.before(Date())) || date.isTimeLessThan24Hours()
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
Expand Down
7 changes: 7 additions & 0 deletions core/src/main/java/org/openedx/core/extension/StringExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,10 @@ fun String.tagId(): String = this.replaceSpace("_").lowercase(Locale.getDefault(
fun String.takeIfNotEmpty(): String? {
return if (this.isEmpty().not()) this else null
}

fun String.toImageLink(apiHostURL: String): String =
if (this.isLinkValid()) {
this
} else {
(apiHostURL + this).replace(Regex("(?<!:)//"), "/")
}
149 changes: 16 additions & 133 deletions core/src/main/java/org/openedx/core/utils/TimeUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,35 @@ import com.google.gson.internal.bind.util.ISO8601Utils
import org.openedx.core.R
import org.openedx.core.domain.model.StartType
import org.openedx.core.system.ResourceManager
import java.text.DateFormat
import java.text.ParseException
import java.text.ParsePosition
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import java.util.concurrent.TimeUnit
import kotlin.math.ceil

object TimeUtils {

private const val FORMAT_ISO_8601 = "yyyy-MM-dd'T'HH:mm:ss'Z'"
private const val FORMAT_ISO_8601_WITH_TIME_ZONE = "yyyy-MM-dd'T'HH:mm:ssXXX"

private const val SEVEN_DAYS_IN_MILLIS = 604800000L

fun formatToString(date: Date, useRelativeDates: Boolean): String {
return if (useRelativeDates) {
DateUtils.getRelativeTimeSpanString(
date.time,
getCurrentTime(),
DateUtils.DAY_IN_MILLIS,
DateUtils.FORMAT_ABBREV_TIME
).toString()
} else {
val locale = Locale(Locale.getDefault().language)
val dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, locale)
dateFormat.format(date)
}
}

fun getCurrentTime(): Long {
return Calendar.getInstance().timeInMillis
}
Expand Down Expand Up @@ -170,126 +183,6 @@ object TimeUtils {
}
return formattedDate
}

/**
* Method to get the formatted time string in terms of relative time with minimum resolution of minutes.
* For example, if the time difference is 1 minute, it will return "1m ago".
*
* @param date Date object to be formatted.
*/
fun getFormattedTime(date: Date): String {
return DateUtils.getRelativeTimeSpanString(
date.time,
getCurrentTime(),
DateUtils.MINUTE_IN_MILLIS,
DateUtils.FORMAT_ABBREV_TIME
).toString()
}

/**
* Returns a formatted date string for the given date.
*/
fun getCourseFormattedDate(context: Context, date: Date): String {
val inputDate = Calendar.getInstance().also {
it.time = date
it.clearTimeComponents()
}
val daysDifference = getDayDifference(inputDate)

return when {
daysDifference == 0 -> {
context.getString(R.string.core_date_format_today)
}

daysDifference == 1 -> {
context.getString(R.string.core_date_format_tomorrow)
}

daysDifference == -1 -> {
context.getString(R.string.core_date_format_yesterday)
}

daysDifference in -2 downTo -7 -> {
context.getString(
R.string.core_date_format_days_ago,
ceil(-daysDifference.toDouble()).toInt().toString()
)
}

daysDifference in 2..7 -> {
DateUtils.formatDateTime(
context,
date.time,
DateUtils.FORMAT_SHOW_WEEKDAY
)
}

inputDate.get(Calendar.YEAR) != Calendar.getInstance().get(Calendar.YEAR) -> {
DateUtils.formatDateTime(
context,
date.time,
DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_SHOW_YEAR
)
}

else -> {
DateUtils.formatDateTime(
context,
date.time,
DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR
)
}
}
}

fun getAssignmentFormattedDate(context: Context, date: Date): String {
val inputDate = Calendar.getInstance().also {
it.time = date
it.clearTimeComponents()
}
val daysDifference = getDayDifference(inputDate)

return when {
daysDifference == 0 -> {
context.getString(R.string.core_date_format_assignment_due_today)
}

daysDifference == 1 -> {
context.getString(R.string.core_date_format_assignment_due_tomorrow)
}

daysDifference == -1 -> {
context.getString(R.string.core_date_format_assignment_due_yesterday)
}

daysDifference <= -2 -> {
val numberOfDays = ceil(-daysDifference.toDouble()).toInt()
context.resources.getQuantityString(
R.plurals.core_date_format_assignment_due_days_ago,
numberOfDays,
numberOfDays
)
}

else -> {
val numberOfDays = ceil(daysDifference.toDouble()).toInt()
context.resources.getQuantityString(
R.plurals.core_date_format_assignment_due_in,
numberOfDays,
numberOfDays
)
}
}
}

/**
* Returns the number of days difference between the given date and the current date.
*/
private fun getDayDifference(inputDate: Calendar): Int {
val currentDate = Calendar.getInstance().also { it.clearTimeComponents() }
val difference = inputDate.timeInMillis - currentDate.timeInMillis
return TimeUnit.MILLISECONDS.toDays(difference).toInt()
}
}

/**
Expand Down Expand Up @@ -336,16 +229,6 @@ fun Date.clearTime(): Date {
return calendar.time
}

/**
* Extension function to check if the time difference between the given date and the current date is less than 24 hours.
*/
fun Date.isTimeLessThan24Hours(): Boolean {
val calendar = Calendar.getInstance()
calendar.time = this
val timeInMillis = (calendar.timeInMillis - TimeUtils.getCurrentTime()).unaryPlus()
return timeInMillis < TimeUnit.DAYS.toMillis(1)
}

fun Date.toCalendar(): Calendar {
val calendar = Calendar.getInstance()
calendar.time = this
Expand Down
16 changes: 1 addition & 15 deletions core/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,21 +92,7 @@
<string name="core_date_type_next_week" tools:ignore="MissingTranslation">Next Week</string>
<string name="core_date_type_upcoming" tools:ignore="MissingTranslation">Upcoming</string>
<string name="core_date_type_none" tools:ignore="MissingTranslation">None</string>
<string name="core_date_format_today" tools:ignore="MissingTranslation">Today</string>
<string name="core_date_format_tomorrow" tools:ignore="MissingTranslation">Tomorrow</string>
<string name="core_date_format_yesterday" tools:ignore="MissingTranslation">Yesterday</string>
<string name="core_date_format_days_ago" tools:ignore="MissingTranslation">%1$s days ago</string>
<string name="core_date_format_assignment_due_today" tools:ignore="MissingTranslation">Due Today</string>
<string name="core_date_format_assignment_due_tomorrow" tools:ignore="MissingTranslation">Due Tomorrow</string>
<string name="core_date_format_assignment_due_yesterday" tools:ignore="MissingTranslation">Due Yesterday</string>
<plurals name="core_date_format_assignment_due_days_ago" tools:ignore="MissingTranslation">
<item quantity="one">Due %1$d day ago</item>
<item quantity="other">Due %1$d days ago</item>
</plurals>
<plurals name="core_date_format_assignment_due_in" tools:ignore="MissingTranslation">
<item quantity="one">Due in %1$d day</item>
<item quantity="other">Due in %1$d days</item>
</plurals>
<string name="core_date_format_assignment_due" tools:ignore="MissingTranslation">Due %1$s</string>
<plurals name="core_date_items_hidden" tools:ignore="MissingTranslation">
<item quantity="one">%d Item Hidden</item>
<item quantity="other">%d Items Hidden</item>
Expand Down
Loading

0 comments on commit f001577

Please sign in to comment.