Skip to content

Commit 459a943

Browse files
authored
Merge pull request #7 from kiing-dom/feat/mvp
SOLVED: Issue persisting 'Solved' state
2 parents e6a0243 + b4b5335 commit 459a943

File tree

4 files changed

+68
-52
lines changed

4 files changed

+68
-52
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
keepcode.zip
2-
bugs.md
2+
bugs.md
3+
TODO.md

content.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,24 @@ async function getProblemData() {
4545
function waitForContentAndStore() {
4646
const observer = new MutationObserver(async () => {
4747
const titleEl = document.querySelector("div");
48-
if (titleEl && titleEl.textContent.trim()) {
48+
if (titleEl?.textContent.trim()) {
4949
observer.disconnect();
5050
const data = await getProblemData();
5151
if (!data) return; // Don't store invalid/undefined problems
52-
browser.storage.local.set({ [data.slug]: data }).then(() => {
53-
console.log("Saved to storage:", data);
54-
}).catch((err) => {
55-
console.error("Storage error:", err);
52+
// Only update non-status fields, always preserve status/solvedAt
53+
browser.storage.local.get(data.slug).then((existing) => {
54+
const prev = existing[data.slug] || {};
55+
// Always preserve status and solvedAt if they exist
56+
if (prev.status) data.status = prev.status;
57+
if (prev.solvedAt) data.solvedAt = prev.solvedAt;
58+
browser.storage.local.set({ [data.slug]: data }).then(() => {
59+
console.log("Saved to storage (non-status fields updated):", data);
60+
}).catch((err) => {
61+
console.error("Storage error:", err);
62+
});
63+
// Start watching for submission result after we have the slug
64+
waitForSubmissionResult(data.slug);
5665
});
57-
// Start watching for submission result after we have the slug
58-
waitForSubmissionResult(data.slug);
5966
}
6067
});
6168

@@ -65,7 +72,7 @@ function waitForContentAndStore() {
6572
function waitForSubmissionResult(slug) {
6673
const observer = new MutationObserver(() => {
6774
const resultEl = document.querySelector('span[data-e2e-locator="submission-result"]');
68-
if (resultEl && resultEl.textContent.includes("Accepted")) {
75+
if (resultEl?.textContent.includes("Accepted")) {
6976
console.log("✅ Accepted detected via submission result!");
7077

7178
browser.storage.local.get(slug).then((existing) => {

manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"manifest_version": 2,
33
"name": "KeepCode",
4-
"version": "0.2.0",
5-
"description": "Focus on answering problems, let KeepCode handle the rest",
4+
"version": "0.2.1",
5+
"description": "Prep smarter for coding interviews: KeepCode tracks your LeetCode progress so you can focus on solving.",
66
"permissions": ["storage", "tabs", "activeTab", "https://leetcode.com/*"],
77
"background": {
88
"scripts": ["background.js"],

popup/popup.js

Lines changed: 49 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,41 +10,53 @@ document.addEventListener("DOMContentLoaded", () => {
1010
return;
1111
}
1212

13-
browser.runtime
14-
.sendMessage({ type: "GET_PROBLEM_DATA", slug })
15-
.then((data) => {
16-
const container = document.getElementById("popupContent");
17-
if (!data) {
18-
container.innerHTML = "<p>To track a problem please visit a leetcode problem page</p>";
19-
return;
20-
}
13+
const container = document.getElementById("popupContent");
2114

22-
container.innerHTML = "";
23-
const titleEl = document.createElement("h3");
24-
titleEl.textContent = `Problem: ${data.title}`;
25-
const diffEl = document.createElement("p");
26-
diffEl.textContent = `Difficulty: ${data.difficulty} `;
27-
const statusEl = document.createElement("p");
28-
statusEl.id = "status";
29-
const strongEl = document.createElement("strong");
30-
strongEl.textContent = data.status || "Unsolved";
31-
statusEl.appendChild(strongEl);
32-
container.appendChild(titleEl);
33-
container.appendChild(diffEl);
34-
container.appendChild(statusEl);
35-
36-
// Listen for problem solved message
37-
browser.runtime.onMessage.addListener((msg) => {
38-
if (msg.type === "PROBLEM_SOLVED" && msg.slug === data.slug) {
39-
const statusEl = document.getElementById("status");
40-
if (statusEl) statusEl.textContent = "Solved ✅";
41-
}
42-
});
43-
})
44-
.catch((err) => {
45-
document.getElementById("popupContent").innerHTML = "<p>Unable to read this page</p>";
46-
console.error(err);
15+
browser.storage.local.get(slug).then((result) => {
16+
let data = result[slug];
17+
if (data) {
18+
renderCurrentProblem(data);
19+
} else {
20+
21+
browser.runtime
22+
.sendMessage({ type: "GET_PROBLEM_DATA", slug })
23+
.then((data) => {
24+
if (data) {
25+
renderCurrentProblem(data);
26+
} else {
27+
container.innerHTML = "<p>To track a problem please visit a leetcode problem page</p>";
28+
}
29+
})
30+
.catch((err) => {
31+
container.innerHTML = "<p>Unable to read this page.</p>";
32+
console.error(err);
33+
});
34+
}
35+
});
36+
37+
function renderCurrentProblem(data) {
38+
container.innerHTML = "";
39+
const titleEl = document.createElement("h3");
40+
titleEl.textContent = `Problem: ${data.title}`;
41+
const diffEl = document.createElement("p");
42+
diffEl.textContent = `Difficulty: ${data.difficulty} `;
43+
const statusEl = document.createElement("p");
44+
statusEl.id = "status";
45+
const strongEl = document.createElement("strong");
46+
strongEl.textContent = data.status || "Unsolved";
47+
statusEl.appendChild(strongEl);
48+
container.appendChild(titleEl);
49+
container.appendChild(diffEl);
50+
container.appendChild(statusEl);
51+
52+
// Listen for problem solved message
53+
browser.runtime.onMessage.addListener((msg) => {
54+
if (msg.type === "PROBLEM_SOLVED" && msg.slug === data.slug) {
55+
const statusEl = document.getElementById("status");
56+
if (statusEl) statusEl.textContent = "Solved ✅";
57+
}
4758
});
59+
}
4860
});
4961
});
5062

@@ -62,10 +74,9 @@ document.addEventListener("DOMContentLoaded", () => {
6274
p.difficulty !== "Unknown Difficulty" &&
6375
p.status === "Solved"
6476
);
65-
// Sort by solvedAt descending (most recent first)
77+
6678
problems.sort((a, b) => (b.solvedAt || 0) - (a.solvedAt || 0));
6779

68-
// Collect all unique tags (flattened)
6980
const tagSet = new Set();
7081
problems.forEach((p) => {
7182
if (Array.isArray(p.tags)) {
@@ -94,7 +105,6 @@ document.addEventListener("DOMContentLoaded", () => {
94105
}
95106
}
96107

97-
// Render problems (filtered and limited)
98108
function renderProblems() {
99109
const list = document.getElementById("solvedList");
100110
list.innerHTML = "";
@@ -115,7 +125,7 @@ document.addEventListener("DOMContentLoaded", () => {
115125
const difficultyClass = problem.difficulty
116126
? problem.difficulty.toLowerCase()
117127
: "";
118-
// Use DOM methods instead of innerHTML for safety
128+
119129
const link = document.createElement("a");
120130
link.href = problem.url;
121131
link.target = "_blank";
@@ -148,12 +158,11 @@ document.addEventListener("DOMContentLoaded", () => {
148158
renderProblems();
149159
});
150160

151-
// View All link opens options page
152161
const viewAllLink = document.getElementById("viewAllLink");
153162
if (viewAllLink) {
154163
viewAllLink.addEventListener("click", (e) => {
155164
e.preventDefault();
156-
if (browser.runtime && browser.runtime.openOptionsPage) {
165+
if (browser.runtime?.openOptionsPage) {
157166
browser.runtime.openOptionsPage();
158167
} else {
159168
window.open("../options/options.html", "_blank");
@@ -166,10 +175,9 @@ document.addEventListener("DOMContentLoaded", () => {
166175
const optionsBtn = document.getElementById("optionsBtn");
167176
if (optionsBtn) {
168177
optionsBtn.addEventListener("click", () => {
169-
if (browser.runtime && browser.runtime.openOptionsPage) {
178+
if (browser.runtime?.openOptionsPage) {
170179
browser.runtime.openOptionsPage();
171180
} else {
172-
// fallback for browsers that don't support openOptionsPage
173181
window.open("../options/options.html", "_blank");
174182
}
175183
});

0 commit comments

Comments
 (0)