From f42fed01e1a9d7edea0282926cee3383cf05788e Mon Sep 17 00:00:00 2001 From: Frederick Yin Date: Tue, 25 Jul 2023 15:09:30 +0800 Subject: Separate JavaScript code from UI --- contents/ui/main.qml | 167 ++------------------------------------------------- 1 file changed, 5 insertions(+), 162 deletions(-) (limited to 'contents/ui/main.qml') 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() } } } -- cgit v1.2.3