-
Notifications
You must be signed in to change notification settings - Fork 37
/
course.ts
102 lines (88 loc) · 3.43 KB
/
course.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import { courseUrl, currentCourse, currentLo } from "$lib/stores";
import type { Lo, Course, Lab } from "$lib/services/models/lo-types";
import { decorateCourseTree } from "./models/lo-tree";
import { LiveLab } from "./models/live-lab";
import { presenceService } from "./presence";
import { PUBLIC_party_kit_main_room } from "$env/static/public";
export const courseService = {
courses: new Map<string, Course>(),
labs: new Map<string, LiveLab>(),
courseUrl: "",
async getOrLoadCourse(courseId: string, fetchFunction: typeof fetch): Promise<Course> {
let course = this.courses.get(courseId);
let courseUrl = courseId;
function isValidURL(url: string) {
const urlPattern = /^(https?:\/\/)?([A-Za-z0-9.-]+\.[A-Za-z]{2,})(:[0-9]+)?(\/[A-Za-z0-9_.-]+)*(\/[A-Za-z0-9_.-]+\?[A-Za-z0-9_=-]+)?(#.*)?$/;
return urlPattern.test(url);
}
if (!course) {
if (isValidURL(courseId)) {
if (courseId.includes(".netlify.app")) {
courseUrl = courseId;
courseId = courseId.replace(".netlify.app", "");
} else {
courseUrl = courseId;
}
} else {
courseUrl = `${courseId}.netlify.app`;
}
try {
const response = await fetchFunction(`https://${courseUrl}/tutors.json`);
if (!response.ok) {
throw new Error(`Fetch failed with status ${response.status}`);
}
const data = await response.json();
course = data as Course;
decorateCourseTree(course, courseId, courseUrl);
this.courses.set(courseId, course);
} catch (error) {
console.error(`Error fetching from URL: https://${courseUrl}/tutors.json`);
console.error(error);
throw error;
}
}
return course;
},
async readCourse(courseId: string, fetchFunction: typeof fetch): Promise<Course> {
const course = await this.getOrLoadCourse(courseId, fetchFunction);
currentCourse.set(course);
currentLo.set(course);
courseUrl.set(course.courseUrl);
if (PUBLIC_party_kit_main_room !== "XXX") {
presenceService.startPresenceService(course);
}
return course;
},
async readTopic(courseId: string, topicId: string, fetchFunction: typeof fetch): Promise<Lo> {
const course = await this.readCourse(courseId, fetchFunction);
const topic = course.topicIndex.get(topicId);
if (topic) currentLo.set(topic);
return topic!;
},
async readLab(courseId: string, labId: string, fetchFunction: typeof fetch): Promise<LiveLab> {
const course = await this.readCourse(courseId, fetchFunction);
const lastSegment = labId.substring(labId.lastIndexOf("/") + 1);
if (!lastSegment.startsWith("book")) {
labId = labId.slice(0, labId.lastIndexOf("/"));
}
let liveLab = this.labs.get(labId);
if (!liveLab) {
const lab = course.loIndex.get(labId) as Lab;
liveLab = new LiveLab(course, lab, labId);
this.labs.set(labId, liveLab);
}
currentLo.set(liveLab.lab);
return liveLab;
},
async readWall(courseId: string, type: string, fetchFunction: typeof fetch): Promise<Lo[]> {
const course = await this.readCourse(courseId, fetchFunction);
const wall = course.wallMap?.get(type);
return wall!;
},
async readLo(courseId: string, loId: string, fetchFunction: typeof fetch): Promise<Lo> {
const course = await this.readCourse(courseId, fetchFunction);
const lo = course.loIndex.get(loId);
if (lo) currentLo.set(lo);
return lo!;
}
};