summaryrefslogtreecommitdiff
path: root/contents/ui/main.qml
diff options
context:
space:
mode:
authorFrederick Yin <fkfd@fkfd.me>2023-07-25 15:09:30 +0800
committerFrederick Yin <fkfd@fkfd.me>2023-07-25 15:09:30 +0800
commitf42fed01e1a9d7edea0282926cee3383cf05788e (patch)
treeacfce58f63690e5a8180595c3a8fcf82ce22012a /contents/ui/main.qml
parent33767a83f7ac32e182101bb0a9333a1f9395a158 (diff)
Separate JavaScript code from UI
Diffstat (limited to 'contents/ui/main.qml')
-rw-r--r--contents/ui/main.qml167
1 files changed, 5 insertions, 162 deletions
diff --git a/contents/ui/main.qml b/contents/ui/main.qml
index 006e81b..8a5d7f0 100644
--- a/contents/ui/main.qml
+++ b/contents/ui/main.qml
@@ -8,6 +8,8 @@ import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.components 3.0 as PlasmaComponents3
import org.kde.plasma.extras 2.0 as PlasmaExtras
+import "kanvas.js" as Kanvas
+
Item {
width: PlasmaCore.Units.gridUnit * 20
height: PlasmaCore.Units.gridUnit * 40
@@ -18,174 +20,15 @@ Item {
readonly property string oauth2Token: plasmoid.configuration.oauth2Token
readonly property string authHeader: `Bearer ${oauth2Token}`
- function callApi(path, perPage, callback) {
- let xhr = new XMLHttpRequest()
- let apiUrl = `${apiEndpoint}${path}`
- if (perPage >= 1) {
- // add pagination parameter
- apiUrl += `${path.includes("?") ? "&" : "?"}per_page=${perPage}`
- }
- xhr.open("GET", apiUrl)
- xhr.setRequestHeader("Authorization", authHeader)
- xhr.onload = () => {
- if (xhr.status == 200) {
- try {
- let json = JSON.parse(xhr.responseText)
- if (callback) { callback(json) }
- } catch (e) {
- if (e instanceof SyntaxError) {
- console.error(`Cannot parse response for ${path} as JSON:\n${xhr.responseText}`)
- } else { throw e }
- }
- } else {
- console.error(`XHR failed when retrieving ${path} (status ${xhr.status}):\n${xhr.responseText}`)
- }
- }
- xhr.send()
- }
-
- function syncCanvas() {
- const courses = plasmoid.configuration.courses.split("\n").map(
- // each line in the "courses" config consists of
- // a numeric course id, a space, and a course code
- line => {
- const spaceIndex = line.indexOf(" ")
- return {id: line.slice(0, spaceIndex), code: line.slice(spaceIndex + 1)}
- }
- )
- let courseIndices = {} // reverse look-up table to sort by courses
- for (let i = 0; i < courses.length; i++) {
- courseIndices[courses[i].id] = i
- }
-
- const showSubmittedAssignments = plasmoid.configuration.showSubmittedAssignments
-
- // we need user id to check submission status
- callApi("/users/self", 0, user => {
- syncCourses(courses, courseIndices, showSubmittedAssignments, user.id)
- })
- }
-
- // fetch asynchronously, but display in this order:
- // important -> normal -> finished
- // when an activity is both important and finished, important takes priority
- function syncCourses(courses, courseIndices, showSubmittedAssignments, userId) {
- announcementsModel.clear()
- assignmentsModel.clear()
-
- let announcementIndices = {
- important: 0, // actually constant, kept for symmetry
- normal: 0,
- finished: 0,
- }
- let assignmentIndices = {
- important: 0,
- normal: 0,
- finished: 0,
- }
-
- for (let course of courses) {
- const courseIdx = courseIndices[course.id]
- callApi(`/announcements?context_codes[]=course_${course.id}`, 50, announcements => {
- announcements.forEach(announcement => {
- const info = {
- type: "announcement",
- activityId: announcement.id,
- courseId: course.id,
- course: course.code,
- title: announcement.title,
- url: announcement.html_url,
- important: plasmoid.configuration.importantAnnouncements.includes(announcement.id.toString()),
- finished: plasmoid.configuration.finishedAnnouncements.includes(announcement.id.toString()),
- }
-
- // figure out where we insert it into list
- let idx = 0
- let endIdx = 0 // actually past the end
- if (info.important) {
- idx = announcementIndices.important
- endIdx = announcementIndices.normal
- announcementIndices.normal++
- announcementIndices.finished++
- } else if (!info.finished) {
- idx = announcementIndices.normal
- endIdx = announcementIndices.finished
- announcementIndices.finished++
- } else {
- idx = announcementIndices.finished
- endIdx = announcementsModel.count
- }
-
- for (; idx < endIdx; idx++) {
- const annc = announcementsModel.get(idx)
- if (courseIndices[course.id] < courseIndices[annc.courseId]) {
- // we are just past the end of this course
- // insert this announcement here
- break
- }
- }
- announcementsModel.insert(idx, info)
- })
- })
-
- callApi(`/courses/${course.id}/assignments`, 50, assignments => {
- assignments.forEach(assignment => {
- callApi(`/courses/${course.id}/assignments/${assignment.id}/submissions/${userId}`, 0, submission => {
- const submitted = submission.workflow_state == "submitted" ||
- submission.workflow_state == "graded"
- if (submitted && !showSubmittedAssignments) return // discard this
-
- const info = {
- type: "assignment",
- activityId: assignment.id,
- courseId: course.id,
- course: course.code,
- title: assignment.name,
- dueAt: assignment.due_at || "", // if null, use empty string to suppress errors
- submitted: submitted,
- url: assignment.html_url,
- important: plasmoid.configuration.importantAssignments.includes(assignment.id.toString()),
- finished: plasmoid.configuration.finishedAssignments.includes(assignment.id.toString()),
- }
-
- let idx = 0
- let endIdx = 0
- if (info.important) {
- idx = assignmentIndices.important
- endIdx = assignmentIndices.normal
- assignmentIndices.normal++
- assignmentIndices.finished++
- } else if (!info.finished) {
- idx = assignmentIndices.normal
- endIdx = assignmentIndices.finished
- assignmentIndices.finished++
- } else {
- idx = assignmentIndices.finished
- endIdx = assignmentsModel.count
- }
-
- for (; idx < endIdx; idx++) {
- const annc = assignmentsModel.get(idx)
- if (courseIndices[course.id] < courseIndices[annc.courseId]) {
- break
- }
- }
- assignmentsModel.insert(idx, info)
- })
- })
- })
- }
- }
-
// sync on initialization
- Component.onCompleted: syncCanvas()
+ Component.onCompleted: Kanvas.syncCanvas()
// update every refreshInterval minutes
Timer {
interval: plasmoid.configuration.refreshInterval * 60 * 1000
running: true
repeat: true
- onTriggered: syncCanvas()
+ onTriggered: Kanvas.syncCanvas()
}
// top level layout
@@ -291,7 +134,7 @@ Item {
PlasmaComponents3.Button {
icon.name: "view-refresh"
text: i18n("Refresh")
- onClicked: syncCanvas()
+ onClicked: Kanvas.syncCanvas()
}
}
}