-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathexerciseDecorationProvider.ts
88 lines (73 loc) · 2.99 KB
/
exerciseDecorationProvider.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import * as vscode from "vscode";
import WorkspaceManager, { WorkspaceExercise } from "../api/workspaceManager";
import { UserData } from "../config/userdata";
/**
* Class that adds decorations like completion icons for exercises.
*/
export default class ExerciseDecorationProvider
implements vscode.Disposable, vscode.FileDecorationProvider
{
public onDidChangeFileDecorations: vscode.Event<vscode.Uri | vscode.Uri[] | undefined>;
private static _passedExercise = new vscode.FileDecoration(
"⬤",
"Exercise completed!",
new vscode.ThemeColor("gitDecoration.addedResourceForeground"),
);
private static _partiallyCompletedExercise = new vscode.FileDecoration(
"○",
"Some points gained",
new vscode.ThemeColor("gitDecoration.modifiedResourceForeground"),
);
private static _missingExercise = new vscode.FileDecoration(
"ⓘ",
"Exercise not found in course. This could be an old exercise that has been renamed or removed from course.",
new vscode.ThemeColor("gitDecoration.ignoredResourceForeground"),
);
private static _expiredExercise = new vscode.FileDecoration("✗", "Deadline exceeded.");
private _eventEmiter: vscode.EventEmitter<vscode.Uri | vscode.Uri[]>;
/**
* Creates a new instance of an `ExerciseDecorationProvider`.
*/
constructor(
private readonly userData: UserData,
private readonly workspaceManager: WorkspaceManager,
) {
this._eventEmiter = new vscode.EventEmitter();
this.onDidChangeFileDecorations = this._eventEmiter.event;
}
public dispose(): void {
this._eventEmiter.dispose();
}
public provideFileDecoration(uri: vscode.Uri): vscode.ProviderResult<vscode.FileDecoration> {
const exercise = this.workspaceManager.getExerciseByPath(uri);
if (!exercise || exercise.uri.fsPath !== uri.fsPath) {
return;
}
const apiExercise = this.userData.getExerciseByName(
exercise.courseSlug,
exercise.exerciseSlug,
);
if (!apiExercise) {
return ExerciseDecorationProvider._missingExercise;
}
if (apiExercise.passed) {
return ExerciseDecorationProvider._passedExercise;
}
const deadlinePassed = apiExercise.deadline
? Date.now() > Date.parse(apiExercise.deadline)
: undefined;
if (deadlinePassed) {
return ExerciseDecorationProvider._expiredExercise;
}
if (apiExercise.awardedPoints > 0) {
return ExerciseDecorationProvider._partiallyCompletedExercise;
}
}
/**
* Trigger decorator event for given exercises. Requires this object to be registered with
* `vscode.window.registerFileDecorationProvider` for any effects to take any effect.
*/
public updateDecorationsForExercises(...exercises: ReadonlyArray<WorkspaceExercise>): void {
this._eventEmiter.fire(exercises.map((x) => x.uri));
}
}