diff --git a/Core/Core/Extensions/DateExtension.swift b/Core/Core/Extensions/DateExtension.swift index 1510d35f6..cb07e81f6 100644 --- a/Core/Core/Extensions/DateExtension.swift +++ b/Core/Core/Extensions/DateExtension.swift @@ -33,42 +33,53 @@ public extension Date { self.init(timeInterval: 0, since: date) } - func timeAgoDisplay() -> String { + func timeAgoDisplay(dueIn: Bool = false) -> String { let currentDate = Date() let calendar = Calendar.current + let dueString = dueIn ? CoreLocalization.Date.due : "" + let dueInString = dueIn ? CoreLocalization.Date.dueIn : "" + let startOfCurrentDate = calendar.startOfDay(for: currentDate) let startOfSelfDate = calendar.startOfDay(for: self) + let daysRemaining = Calendar.current.dateComponents( + [.day], + from: startOfCurrentDate, + to: self + ).day ?? 0 + // Calculate date ranges guard let sevenDaysAgo = calendar.date(byAdding: .day, value: -7, to: startOfCurrentDate), let sevenDaysAhead = calendar.date(byAdding: .day, value: 7, to: startOfCurrentDate) else { - return self.dateToString(style: .mmddyy, useRelativeDates: false) + return dueInString + self.dateToString(style: .mmddyy, useRelativeDates: false) } - let isCurrentYear = calendar.component(.year, from: self) == calendar.component(.year, from: currentDate) + let isCurrentYear = calendar.component(.year, from: self) == calendar.component(.year, from: startOfCurrentDate) - if calendar.isDateInToday(self) { - return CoreLocalization.Date.today + if calendar.isDateInToday(startOfSelfDate) { + return dueString + CoreLocalization.Date.today } - if calendar.isDateInYesterday(self) { - return CoreLocalization.yesterday + if calendar.isDateInYesterday(startOfSelfDate) { + return dueString + CoreLocalization.yesterday } - if calendar.isDateInTomorrow(self) { - return CoreLocalization.tomorrow + if calendar.isDateInTomorrow(startOfSelfDate) { + return dueString + CoreLocalization.tomorrow } if startOfSelfDate > startOfCurrentDate && startOfSelfDate <= sevenDaysAhead { let weekdayFormatter = DateFormatter() weekdayFormatter.dateFormat = "EEEE" if startOfSelfDate == calendar.date(byAdding: .day, value: 1, to: startOfCurrentDate) { - return CoreLocalization.tomorrow + return dueInString + CoreLocalization.tomorrow } else if startOfSelfDate == calendar.date(byAdding: .day, value: 7, to: startOfCurrentDate) { return CoreLocalization.Date.next(weekdayFormatter.string(from: startOfSelfDate)) } else { - return weekdayFormatter.string(from: startOfSelfDate) + return dueIn ? ( + CoreLocalization.Date.dueInDays(daysRemaining) + ) : weekdayFormatter.string(from: startOfSelfDate) } } @@ -81,7 +92,7 @@ public extension Date { let specificFormatter = DateFormatter() specificFormatter.dateFormat = isCurrentYear ? "MMMM d" : "MMMM d, yyyy" - return specificFormatter.string(from: self) + return dueInString + specificFormatter.string(from: self) } func isDateInNextWeek(date: Date, currentDate: Date) -> Bool { @@ -148,13 +159,13 @@ public extension Date { return totalSeconds } - func dateToString(style: DateStringStyle, useRelativeDates: Bool) -> String { + func dateToString(style: DateStringStyle, useRelativeDates: Bool, dueIn: Bool = false) -> String { let dateFormatter = DateFormatter() dateFormatter.locale = .current if useRelativeDates { - return timeAgoDisplay() + return timeAgoDisplay(dueIn: dueIn) } else { switch style { case .courseStartsMonthDDYear: @@ -213,7 +224,9 @@ public extension Date { case .iso8601: return date case .shortWeekdayMonthDayYear: - return getShortWeekdayMonthDayYear(dateFormatterString: date) + return ( + dueIn ? CoreLocalization.Date.dueIn : "" + ) + getShortWeekdayMonthDayYear(dateFormatterString: date) } } diff --git a/Core/Core/SwiftGen/Strings.swift b/Core/Core/SwiftGen/Strings.swift index ba641c990..ed9aa825d 100644 --- a/Core/Core/SwiftGen/Strings.swift +++ b/Core/Core/SwiftGen/Strings.swift @@ -141,6 +141,14 @@ public enum CoreLocalization { public static func daysAgo(_ p1: Any) -> String { return CoreLocalization.tr("Localizable", "DATE.DAYS_AGO", String(describing: p1), fallback: "%@ Days Ago") } + /// Due + public static let due = CoreLocalization.tr("Localizable", "DATE.DUE", fallback: "Due ") + /// Due in + public static let dueIn = CoreLocalization.tr("Localizable", "DATE.DUE_IN", fallback: "Due in ") + /// Due in %@ Days + public static func dueInDays(_ p1: Any) -> String { + return CoreLocalization.tr("Localizable", "DATE.DUE_IN_DAYS", String(describing: p1), fallback: "Due in %@ Days") + } /// Ended public static let ended = CoreLocalization.tr("Localizable", "DATE.ENDED", fallback: "Ended") /// Just now diff --git a/Core/Core/en.lproj/Localizable.strings b/Core/Core/en.lproj/Localizable.strings index 806b411a1..b7bc68aad 100644 --- a/Core/Core/en.lproj/Localizable.strings +++ b/Core/Core/en.lproj/Localizable.strings @@ -56,6 +56,9 @@ "DATE.TODAY" = "Today"; "DATE.NEXT" = "Next %@"; "DATE.DAYS_AGO" = "%@ Days Ago"; +"DATE.DUE" = "Due "; +"DATE.DUE_IN" = "Due in "; +"DATE.DUE_IN_DAYS" = "Due in %@ Days"; "ALERT.ACCEPT" = "ACCEPT"; "ALERT.CANCEL" = "CANCEL"; diff --git a/Dashboard/Dashboard/Presentation/Elements/PrimaryCardView.swift b/Dashboard/Dashboard/Presentation/Elements/PrimaryCardView.swift index 1e58a4fa6..83680dc7c 100644 --- a/Dashboard/Dashboard/Presentation/Elements/PrimaryCardView.swift +++ b/Dashboard/Dashboard/Presentation/Elements/PrimaryCardView.swift @@ -113,9 +113,10 @@ public struct PrimaryCardView: View { ).day ?? 0 courseButton( title: futureAssignment.title, - description: DashboardLocalization.Learn.PrimaryCard.dueDays( - futureAssignment.type, - daysRemaining + description: futureAssignment.date.dateToString( + style: .shortWeekdayMonthDayYear, + useRelativeDates: useRelativeDates, + dueIn: true ), icon: CoreAssets.chapter.swiftUIImage, selected: false, @@ -264,13 +265,22 @@ struct PrimaryCardView_Previews: PreviewProvider { courseImage: "https://thumbs.dreamstime.com/b/logo-edx-samsung-tablet-edx-massive-open-online-course-mooc-provider-hosts-online-university-level-courses-wide-117763805.jpg", courseStartDate: nil, courseEndDate: Date(), - futureAssignments: [], + futureAssignments: [ + Assignment( + type: "Lesson", + title: "HomeWork", + description: "Some description", + date: Date().addingTimeInterval(64000 * 3), + complete: false, + firstComponentBlockId: "123" + ) + ], pastAssignments: [], progressEarned: 10, progressPossible: 45, canResume: true, resumeTitle: "Course Chapter 1", - useRelativeDates: true, + useRelativeDates: false, assignmentAction: { _ in }, openCourseAction: {}, resumeAction: {}