diff --git a/src/components/FrameRenderer/renderer.ts b/src/components/FrameRenderer/renderer.ts
index 9cf5effb9..63ad29a77 100644
--- a/src/components/FrameRenderer/renderer.ts
+++ b/src/components/FrameRenderer/renderer.ts
@@ -2,13 +2,19 @@ import { wireframeJSONToSVG } from 'roadmap-renderer';
import { httpPost } from '../../lib/http';
import { isLoggedIn } from '../../lib/jwt';
import {
+ refreshProgressCounters,
renderResourceProgress,
+ renderTopicProgress,
+ ResourceProgressType,
ResourceType,
+ updateResourceProgress,
} from '../../lib/resource-progress';
+import { pageProgressMessage } from '../../stores/page';
+import { showLoginPopup } from '../../lib/popup';
export class Renderer {
resourceId: string;
- resourceType: string;
+ resourceType: ResourceType | string;
jsonUrl: string;
loaderHTML: string | null;
@@ -28,8 +34,10 @@ export class Renderer {
this.onDOMLoaded = this.onDOMLoaded.bind(this);
this.jsonToSvg = this.jsonToSvg.bind(this);
this.handleSvgClick = this.handleSvgClick.bind(this);
+ this.handleSvgRightClick = this.handleSvgRightClick.bind(this);
this.prepareConfig = this.prepareConfig.bind(this);
this.switchRoadmap = this.switchRoadmap.bind(this);
+ this.updateTopicStatus = this.updateTopicStatus.bind(this);
}
get loaderEl() {
@@ -161,6 +169,53 @@ export class Renderer {
this.jsonToSvg(newJsonUrl)?.then(() => {});
}
+ updateTopicStatus(topicId: string, newStatus: ResourceProgressType) {
+ if (!isLoggedIn()) {
+ showLoginPopup();
+ return;
+ }
+
+ pageProgressMessage.set('Updating progress');
+ updateResourceProgress(
+ {
+ resourceId: this.resourceId,
+ resourceType: this.resourceType as ResourceType,
+ topicId,
+ },
+ newStatus
+ )
+ .then(() => {
+ renderTopicProgress(topicId, newStatus);
+ refreshProgressCounters();
+ })
+ .catch((err) => {
+ alert('Something went wrong, please try again.');
+ console.error(err);
+ })
+ .finally(() => {
+ pageProgressMessage.set('');
+ });
+
+ return;
+ }
+
+ handleSvgRightClick(e: any) {
+ const targetGroup = e.target?.closest('g') || {};
+ const groupId = targetGroup.dataset ? targetGroup.dataset.groupId : '';
+ if (!groupId) {
+ return;
+ }
+
+ e.preventDefault();
+
+ const isCurrentStatusDone = targetGroup.classList.contains('done');
+ const normalizedGroupId = groupId.replace(/^\d+-/, '');
+ this.updateTopicStatus(
+ normalizedGroupId,
+ !isCurrentStatusDone ? 'done' : 'pending'
+ );
+ }
+
handleSvgClick(e: any) {
const targetGroup = e.target?.closest('g') || {};
const groupId = targetGroup.dataset ? targetGroup.dataset.groupId : '';
@@ -209,6 +264,28 @@ export class Renderer {
// Remove sorting prefix from groupId
const normalizedGroupId = groupId.replace(/^\d+-/, '');
+ const isCurrentStatusLearning = targetGroup.classList.contains('learning');
+ const isCurrentStatusSkipped = targetGroup.classList.contains('skipped');
+
+ if (e.shiftKey) {
+ e.preventDefault();
+ this.updateTopicStatus(
+ normalizedGroupId,
+ !isCurrentStatusLearning ? 'learning' : 'pending'
+ );
+ return;
+ }
+
+ if (e.altKey) {
+ e.preventDefault();
+ this.updateTopicStatus(
+ normalizedGroupId,
+ !isCurrentStatusSkipped ? 'skipped' : 'pending'
+ );
+
+ return;
+ }
+
window.dispatchEvent(
new CustomEvent(`${this.resourceType}.topic.click`, {
detail: {
@@ -223,7 +300,7 @@ export class Renderer {
init() {
window.addEventListener('DOMContentLoaded', this.onDOMLoaded);
window.addEventListener('click', this.handleSvgClick);
- // window.addEventListener('contextmenu', this.handleSvgClick);
+ window.addEventListener('contextmenu', this.handleSvgRightClick);
}
}
diff --git a/src/components/ProgressHelpPopup.astro b/src/components/ProgressHelpPopup.astro
new file mode 100644
index 000000000..3aa6d92ec
--- /dev/null
+++ b/src/components/ProgressHelpPopup.astro
@@ -0,0 +1,47 @@
+---
+import AstroIcon from './AstroIcon.astro';
+import Popup from './Popup/Popup.astro';
+---
+
+
+ Login and use one of the options listed below.
+
+ Click the roadmap topics and use Update Progress dropdown to update your progress.
+ Use the keyboard shortcuts listed below.
+ Track your Progress
+
+
+
+
- - - 0% Done - - - - 0 of 0 Done - + + 0 of 0 Done + +
diff --git a/src/components/RoadmapHeader.astro b/src/components/RoadmapHeader.astro index c1c7ba6d1..5cbb0595f 100644 --- a/src/components/RoadmapHeader.astro +++ b/src/components/RoadmapHeader.astro @@ -5,6 +5,7 @@ import RoadmapHint from './RoadmapHint.astro'; import RoadmapNote from './RoadmapNote.astro'; import TopicSearch from './TopicSearch/TopicSearch.astro'; import YouTubeAlert from './YouTubeAlert.astro'; +import ProgressHelpPopup from './ProgressHelpPopup.astro'; export interface Props { title: string; @@ -32,6 +33,7 @@ const isRoadmapReady = !isUpcoming; ---