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

feat: added styling to CourseDateBlock #194

Merged
merged 3 commits into from
Jan 25, 2024
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
47 changes: 25 additions & 22 deletions core/src/main/java/org/openedx/core/data/model/CourseDates.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import com.google.gson.annotations.SerializedName
import org.openedx.core.domain.model.DatesSection
import org.openedx.core.utils.TimeUtils
import org.openedx.core.utils.addDays
import org.openedx.core.utils.clearTime
import org.openedx.core.utils.isToday
import java.util.Date
import org.openedx.core.domain.model.CourseDateBlock as DomainCourseDateBlock

data class CourseDates(
Expand All @@ -24,7 +26,7 @@ data class CourseDates(
val verifiedUpgradeLink: String? = "",
) {
fun getStructuredCourseDates(): LinkedHashMap<DatesSection, List<DomainCourseDateBlock>> {
val currentDate = TimeUtils.getCurrentDate()
val currentDate = Date()
val courseDatesResponse: LinkedHashMap<DatesSection, List<DomainCourseDateBlock>> =
LinkedHashMap()
val datesList = mapToDomain()
Expand All @@ -36,43 +38,44 @@ data class CourseDates(
datesList.filter { currentDate.after(it.date) }.also { datesList.removeAll(it) }

courseDatesResponse[DatesSection.TODAY] =
datesList.filter { it.date != null && it.date.isToday() }
.also { datesList.removeAll(it) }
datesList.filter { it.date.isToday() }.also { datesList.removeAll(it) }

//Update the date for upcoming comparison without time
currentDate.clearTime()

// for current week except today
courseDatesResponse[DatesSection.THIS_WEEK] = datesList.filter {
it.date != null && it.date.after(currentDate) &&
it.date.before(currentDate.addDays(8))
it.date.after(currentDate) && it.date.before(currentDate.addDays(8))
}.also { datesList.removeAll(it) }

// for coming week
courseDatesResponse[DatesSection.NEXT_WEEK] = datesList.filter {
it.date != null &&
it.date.after(currentDate.addDays(7)) &&
it.date.before(currentDate.addDays(15))
it.date.after(currentDate.addDays(7)) && it.date.before(currentDate.addDays(15))
}.also { datesList.removeAll(it) }

// for upcoming
courseDatesResponse[DatesSection.UPCOMING] = datesList.filter {
it.date != null && it.date.after(currentDate.addDays(14))
it.date.after(currentDate.addDays(14))
}.also { datesList.removeAll(it) }

return courseDatesResponse
}

private fun mapToDomain(): MutableList<DomainCourseDateBlock> {
return courseDateBlocks.map { item ->
DomainCourseDateBlock(
title = item.title,
description = item.description,
link = item.link,
blockId = item.blockId,
date = TimeUtils.iso8601ToDate(item.date),
complete = item.complete,
learnerHasAccess = item.learnerHasAccess,
dateType = item.dateType,
assignmentType = item.assignmentType
)
}.sortedBy { it.date }.filter { it.date != null }.toMutableList()
return courseDateBlocks.mapNotNull { item ->
TimeUtils.iso8601ToDate(item.date)?.let { date ->
DomainCourseDateBlock(
title = item.title,
description = item.description,
link = item.link,
blockId = item.blockId,
date = date,
complete = item.complete,
learnerHasAccess = item.learnerHasAccess,
dateType = item.dateType,
assignmentType = item.assignmentType
)
}
}.sortedBy { it.date }.toMutableList()
}
}
19 changes: 10 additions & 9 deletions core/src/main/java/org/openedx/core/data/model/DateType.kt
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
package org.openedx.core.data.model

import com.google.gson.annotations.SerializedName
import org.openedx.core.R

enum class DateType {
enum class DateType(val drawableResId: Int? = null) {
@SerializedName("todays-date")
TODAY_DATE,
TODAY_DATE(R.drawable.core_ic_calendar),

@SerializedName("course-start-date")
COURSE_START_DATE,
COURSE_START_DATE(R.drawable.core_ic_start_end),

@SerializedName("course-end-date")
COURSE_END_DATE,
COURSE_END_DATE(R.drawable.core_ic_start_end),

@SerializedName("course-expired-date")
COURSE_EXPIRED_DATE,
COURSE_EXPIRED_DATE(R.drawable.core_ic_course_expire),
farhan-arshad-dev marked this conversation as resolved.
Show resolved Hide resolved

@SerializedName("assignment-due-date")
ASSIGNMENT_DUE_DATE,
ASSIGNMENT_DUE_DATE(R.drawable.core_ic_assignment),

@SerializedName("certificate-available-date")
CERTIFICATE_AVAILABLE_DATE,
CERTIFICATE_AVAILABLE_DATE(R.drawable.core_ic_certificate),

@SerializedName("verified-upgrade-deadline")
VERIFIED_UPGRADE_DEADLINE,
VERIFIED_UPGRADE_DEADLINE(R.drawable.core_ic_calendar),

@SerializedName("verification-deadline-date")
VERIFICATION_DEADLINE_DATE,
VERIFICATION_DEADLINE_DATE(R.drawable.core_ic_calendar),

NONE,
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.openedx.core.domain.model

import org.openedx.core.data.model.DateType
import org.openedx.core.utils.isTimeLessThan24Hours
import org.openedx.core.utils.isToday
import java.util.Date

data class CourseDateBlock(
Expand All @@ -10,7 +12,7 @@ data class CourseDateBlock(
val blockId: String = "",
val learnerHasAccess: Boolean = false,
val complete: Boolean = false,
val date: Date?,
val date: Date,
val dateType: DateType = DateType.NONE,
val assignmentType: String? = "",
) {
Expand All @@ -19,7 +21,12 @@ data class CourseDateBlock(
DateType.COURSE_START_DATE,
DateType.COURSE_END_DATE,
DateType.CERTIFICATE_AVAILABLE_DATE,
DateType.VERIFICATION_DEADLINE_DATE
) && date?.before(Date()) == true)
DateType.VERIFIED_UPGRADE_DEADLINE,
DateType.VERIFICATION_DEADLINE_DATE,
) && date.before(Date()))
}

fun isTimeDifferenceLessThan24Hours(): Boolean {
return (date.isToday() && date.before(Date())) || date.isTimeLessThan24Hours()
}
}
85 changes: 50 additions & 35 deletions core/src/main/java/org/openedx/core/utils/TimeUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,6 @@ object TimeUtils {

private const val SEVEN_DAYS_IN_MILLIS = 604800000L

/**
* This method used to get the current date
* @return The current date with time set to midnight.
*/
fun getCurrentDate(): Date {
val calendar = Calendar.getInstance().also { it.clearTimeComponents() }
return calendar.time
}
farhan-arshad-dev marked this conversation as resolved.
Show resolved Hide resolved

fun getCurrentTime(): Long {
return Calendar.getInstance().timeInMillis
}
Expand All @@ -53,15 +44,6 @@ object TimeUtils {
}
}

/**
* This method used to convert the date to ISO 8601 compliant format date string
* @param date [Date]needs to be converted
* @return The current date and time in a ISO 8601 compliant format.
*/
fun dateToIso8601(date: Date?): String {
return ISO8601Utils.format(date, true)
}

fun iso8601ToDateWithTime(context: Context, text: String): String {
return try {
val courseDateFormat = SimpleDateFormat(FORMAT_ISO_8601, Locale.getDefault())
Expand All @@ -75,31 +57,20 @@ object TimeUtils {
}
}

fun dateToCourseDate(resourceManager: ResourceManager, date: Date?): String {
private fun dateToCourseDate(resourceManager: ResourceManager, date: Date?): String {
return formatDate(
format = resourceManager.getString(R.string.core_date_format_MMMM_dd), date = date
)
}

fun formatDate(format: String, date: String): String {
return formatDate(format, iso8601ToDate(date))
}

fun formatDate(format: String, date: Date?): String {
private fun formatDate(format: String, date: Date?): String {
if (date == null) {
return ""
}
val sdf = SimpleDateFormat(format, Locale.getDefault())
return sdf.format(date)
}

fun stringToDate(dateFormat: String, date: String): Date? {
if (dateFormat.isEmpty() || date.isEmpty()) {
return null
}
return SimpleDateFormat(dateFormat, Locale.getDefault()).parse(date)
}

/**
* Checks if the given date is past today.
*
Expand Down Expand Up @@ -200,6 +171,21 @@ 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()
}

farhan-arshad-dev marked this conversation as resolved.
Show resolved Hide resolved
/**
* Returns a formatted date string for the given date.
*/
Expand Down Expand Up @@ -266,27 +252,56 @@ object TimeUtils {
}
}

// Extension function to clear time components
/**
* Extension function to clear time components of a calendar.
* for example, if the time is 10:30:45, it will set the time to 00:00:00
*/
fun Calendar.clearTimeComponents() {
this.set(Calendar.HOUR_OF_DAY, 0)
this.set(Calendar.MINUTE, 0)
this.set(Calendar.SECOND, 0)
this.set(Calendar.MILLISECOND, 0)
}

// Extension function to check if a date is today
/**
* Extension function to check if the given date is today.
*/
fun Date.isToday(): Boolean {
val calendar = Calendar.getInstance()
calendar.time = this
calendar.clearTimeComponents()
return calendar.time == TimeUtils.getCurrentDate()
return calendar.time == Date().clearTime()
}

// Extension function to add number of days to a date
/**
* Extension function to add days to a date.
* for example, if the date is 2020-01-01 10:30:45, and days is 2, it will return 2020-01-03 00:00:00
*/
fun Date.addDays(days: Int): Date {
val calendar = Calendar.getInstance()
calendar.time = this
calendar.clearTimeComponents()
calendar.add(Calendar.DATE, days)
return calendar.time
}

/**
* Extension function to clear time components of a date.
* for example, if the date is 2020-01-01 10:30:45, it will return 2020-01-01 00:00:00
*/
fun Date.clearTime(): Date {
val calendar = Calendar.getInstance()
calendar.time = this
calendar.clearTimeComponents()
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)
}
12 changes: 12 additions & 0 deletions core/src/main/res/drawable/core_ic_assignment.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<group>
<clip-path android:pathData="M0,0h16v16h-16z" />
<path
android:fillColor="#19212F"
android:pathData="M3.333,15.8C2.967,15.8 2.653,15.67 2.392,15.409C2.131,15.148 2,14.834 2,14.467V5.134C2,4.767 2.131,4.453 2.392,4.192C2.653,3.931 2.967,3.801 3.333,3.801H9.283L7.95,5.134H3.333V14.467H12.667V9.834L14,8.501V14.467C14,14.834 13.869,15.148 13.608,15.409C13.347,15.67 13.033,15.8 12.667,15.8H3.333ZM10.783,4.184L11.733,5.117L7.333,9.517V10.467H8.267L12.683,6.051L13.633,6.984L8.833,11.8H6V8.967L10.783,4.184ZM13.633,6.984L10.783,4.184L12.45,2.517C12.717,2.251 13.036,2.117 13.408,2.117C13.781,2.117 14.094,2.251 14.35,2.517L15.283,3.467C15.539,3.723 15.667,4.034 15.667,4.401C15.667,4.767 15.539,5.078 15.283,5.334L13.633,6.984Z" />
</group>
</vector>
9 changes: 9 additions & 0 deletions core/src/main/res/drawable/core_ic_calendar.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:fillColor="#19212F"
android:pathData="M11.333,1.334C10.967,1.334 10.667,1.634 10.667,2.001V2.667H5.333V2.001C5.333,1.634 5.033,1.334 4.667,1.334C4.3,1.334 4,1.634 4,2.001V2.667H3.333C2.593,2.667 2.007,3.267 2.007,4.001L2,13.334C2,14.067 2.593,14.667 3.333,14.667H12.667C13.4,14.667 14,14.067 14,13.334V4.001C14,3.267 13.4,2.667 12.667,2.667H12V2.001C12,1.634 11.7,1.334 11.333,1.334ZM12.667,13.334H3.333V6.667H12.667V13.334ZM7.333,8.667C7.333,8.301 7.633,8.001 8,8.001C8.367,8.001 8.667,8.301 8.667,8.667C8.667,9.034 8.367,9.334 8,9.334C7.633,9.334 7.333,9.034 7.333,8.667ZM4.667,8.667C4.667,8.301 4.967,8.001 5.333,8.001C5.7,8.001 6,8.301 6,8.667C6,9.034 5.7,9.334 5.333,9.334C4.967,9.334 4.667,9.034 4.667,8.667ZM10,8.667C10,8.301 10.3,8.001 10.667,8.001C11.033,8.001 11.333,8.301 11.333,8.667C11.333,9.034 11.033,9.334 10.667,9.334C10.3,9.334 10,9.034 10,8.667ZM7.333,11.334C7.333,10.967 7.633,10.667 8,10.667C8.367,10.667 8.667,10.967 8.667,11.334C8.667,11.701 8.367,12.001 8,12.001C7.633,12.001 7.333,11.701 7.333,11.334ZM4.667,11.334C4.667,10.967 4.967,10.667 5.333,10.667C5.7,10.667 6,10.967 6,11.334C6,11.701 5.7,12.001 5.333,12.001C4.967,12.001 4.667,11.701 4.667,11.334ZM10,11.334C10,10.967 10.3,10.667 10.667,10.667C11.033,10.667 11.333,10.967 11.333,11.334C11.333,11.701 11.033,12.001 10.667,12.001C10.3,12.001 10,11.701 10,11.334Z" />
</vector>
9 changes: 9 additions & 0 deletions core/src/main/res/drawable/core_ic_certificate.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:fillColor="#19212F"
android:pathData="M13.333,4.667H10V2.667C10,1.934 9.4,1.334 8.666,1.334H7.333C6.6,1.334 6,1.934 6,2.667V4.667H2.666C1.933,4.667 1.333,5.267 1.333,6.001V13.334C1.333,14.067 1.933,14.667 2.666,14.667H13.333C14.066,14.667 14.666,14.067 14.666,13.334V6.001C14.666,5.267 14.066,4.667 13.333,4.667ZM6,8.001C6.553,8.001 7,8.447 7,9.001C7,9.554 6.553,10.001 6,10.001C5.446,10.001 5,9.554 5,9.001C5,8.447 5.446,8.001 6,8.001ZM8,12.001H4V11.714C4,11.314 4.24,10.947 4.613,10.787C5.04,10.601 5.506,10.501 6,10.501C6.493,10.501 6.96,10.601 7.386,10.787C7.753,10.947 8,11.307 8,11.714V12.001ZM8.666,6.001H7.333V2.667H8.666V6.001ZM11.5,11.001H9.833C9.56,11.001 9.333,10.774 9.333,10.501C9.333,10.227 9.56,10.001 9.833,10.001H11.5C11.773,10.001 12,10.227 12,10.501C12,10.774 11.773,11.001 11.5,11.001ZM11.5,9.001H9.833C9.56,9.001 9.333,8.774 9.333,8.501C9.333,8.227 9.56,8.001 9.833,8.001H11.5C11.773,8.001 12,8.227 12,8.501C12,8.774 11.773,9.001 11.5,9.001Z" />
</vector>
12 changes: 12 additions & 0 deletions core/src/main/res/drawable/core_ic_course_expire.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:fillColor="#19212F"
android:pathData="M11,7.333C11.467,7.333 11.914,7.399 12.334,7.526V6.666C12.334,5.933 11.734,5.333 11,5.333H10.334V3.999C10.334,2.159 8.84,0.666 7,0.666C5.16,0.666 3.667,2.159 3.667,3.999V5.333H3C2.267,5.333 1.667,5.933 1.667,6.666V13.333C1.667,14.066 2.267,14.666 3,14.666H7.174C6.647,13.913 6.334,12.993 6.334,11.999C6.334,9.419 8.42,7.333 11,7.333ZM5,3.999C5,2.893 5.894,1.999 7,1.999C8.107,1.999 9,2.893 9,3.999V5.333H5V3.999Z" />
<path
android:fillColor="#19212F"
android:pathData="M11,8.666C9.16,8.666 7.667,10.159 7.667,11.999C7.667,13.839 9.16,15.333 11,15.333C12.84,15.333 14.334,13.839 14.334,11.999C14.334,10.159 12.84,8.666 11,8.666ZM12.334,13.333C12.2,13.466 11.994,13.466 11.86,13.333L10.76,12.233C10.7,12.173 10.66,12.086 10.66,11.999V10.333C10.66,10.146 10.807,9.999 10.994,9.999C11.18,9.999 11.327,10.146 11.327,10.333V11.859L12.327,12.859C12.467,12.993 12.467,13.199 12.334,13.333Z" />
</vector>
9 changes: 9 additions & 0 deletions core/src/main/res/drawable/core_ic_lock.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:fillColor="#19212F"
android:pathData="M12,5.667H11.334V4.333C11.334,2.493 9.84,1 8,1C6.16,1 4.667,2.493 4.667,4.333V5.667H4C3.267,5.667 2.667,6.267 2.667,7V13.667C2.667,14.4 3.267,15 4,15H12C12.734,15 13.334,14.4 13.334,13.667V7C13.334,6.267 12.734,5.667 12,5.667ZM8,11.667C7.267,11.667 6.667,11.067 6.667,10.333C6.667,9.6 7.267,9 8,9C8.734,9 9.334,9.6 9.334,10.333C9.334,11.067 8.734,11.667 8,11.667ZM6,5.667V4.333C6,3.227 6.894,2.333 8,2.333C9.107,2.333 10,3.227 10,4.333V5.667H6Z" />
</vector>
12 changes: 12 additions & 0 deletions core/src/main/res/drawable/core_ic_start_end.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="17dp"
android:height="17dp"
android:viewportWidth="17"
android:viewportHeight="17">
<group>
<clip-path android:pathData="M0.854,0.803h16v16h-16z" />
<path
android:fillColor="#19212F"
android:pathData="M8.854,14.803L4.187,12.269V8.269L1.521,6.803L8.854,2.803L16.187,6.803V12.136H14.854V7.536L13.521,8.269V12.269L8.854,14.803ZM8.854,9.269L13.42,6.803L8.854,4.336L4.287,6.803L8.854,9.269ZM8.854,13.286L12.187,11.486V8.969L8.854,10.803L5.521,8.969V11.486L8.854,13.286Z" />
</group>
</vector>
Loading