diff options
-rw-r--r-- | contents/ui/ActivityView.qml | 76 | ||||
-rw-r--r-- | contents/ui/main.qml | 4 |
2 files changed, 77 insertions, 3 deletions
diff --git a/contents/ui/ActivityView.qml b/contents/ui/ActivityView.qml index c08877a..cbbd6f9 100644 --- a/contents/ui/ActivityView.qml +++ b/contents/ui/ActivityView.qml @@ -13,6 +13,80 @@ RowLayout { width: parent.width Layout.fillWidth: true + function sameDay(due, now) { + return ( + due.getFullYear() == now.getFullYear() && + due.getMonth() == now.getMonth() && + due.getDate() == now.getDate() + ) + } + + function dayDiff(due, now, stopAt) { + // due and now are both Date objects + // if due has the same day as now (i.e. due is today), return 0 + // if due is tomorrow, return 1, the day after that 2, yesterday -1, etc. + // when the absolute value of diff reaches stopAt, return stopAt + let diff = 0 + const step = (due > now) ? 1 : -1 + while (!sameDay(due, now)) { + now.setDate(now.getDate() + step) + diff += step + if (Math.abs(diff) >= stopAt) { + return stopAt + } + } + return diff + } + + function humanDue(isoDue) { + // converts ISO 8601 datetime string to relative time, e.g. tomorrow midnight + const daysOfWeek = [ + i18n("Sunday"), + i18n("Monday"), + i18n("Tuesday"), + i18n("Wednesday"), + i18n("Thursday"), + i18n("Friday"), + i18n("Saturday"), + ] + + try { + let due = new Date(isoDue) + if (due.toString() == "Invalid Date") { + console.warn(`Cannot parse due date: ${isoDue}`) + return isoDue + } + + let now = new Date() + const pastDue = (due <= now) + const dayDifference = dayDiff(due, now, 8) + let humanDueString = "" + + if (dayDifference <= -2) { + humanDateString = Qt.formatDate(due) + } else if (dayDifference == -1) { + humanDueString = i18n("Yesterday") + } else if (dayDifference == 0) { + humanDueString = i18n("Today") + } else if (dayDifference == 1) { + humanDueString = i18n("Tomorrow") + } else if (dayDifference <= 6) { + humanDueString = daysOfWeek[due.getDay()] + } else { + humanDueString = Qt.formatDate(due) + } + + humanDueString += " " + Qt.formatTime(due) + + if (pastDue) { + humanDueString += " " + i18n("(missed)") + } + return humanDueString + } catch (e) { + return isoDue // screw it + } + } + RowLayout { Layout.fillWidth: true PlasmaComponents3.CheckBox { @@ -37,7 +111,7 @@ RowLayout { PlasmaComponents3.Label { id: dueLabel visible: type == "assignment" - text: "Due " + (due || "unknown") + text: dueAt ? ("Due: " + humanDue(dueAt)) : "" color: activityLabel.color Layout.fillWidth: true } diff --git a/contents/ui/main.qml b/contents/ui/main.qml index f4eed97..38168d6 100644 --- a/contents/ui/main.qml +++ b/contents/ui/main.qml @@ -72,7 +72,7 @@ Item { activityId: activity.id, course: course[1], title: activity.title, - due: activity.assignment.due_at, + dueAt: activity.assignment.due_at, url: activity.html_url, important, }) @@ -140,7 +140,7 @@ Item { type: "assignment" course: "EE210" title: "Title" - due: "2022-12-31T23:59:59Z" + dueAt: "2022-04-10T15:59:59Z" url: "https://xkcd.com" important: true activityId: 1 |