Skip to content

Commit de7f9b1

Browse files
committed
new icon and flat src
1 parent 8446706 commit de7f9b1

4 files changed

Lines changed: 180 additions & 7 deletions

File tree

manifest.json

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifest_version": 2,
33
"name": "NoteKeeper",
4-
"version": "1.3.0",
4+
"version": "2.0.0",
55
"description": "NoteKeeper transforms your new tab into a minimalist, auto-saving text editor.",
66
"author": "semanticdata",
77
"browser_specific_settings": {
@@ -14,20 +14,29 @@
1414
"storage"
1515
],
1616
"icons": {
17-
"48": "src/icons/icon48.png",
18-
"96": "src/icons/icon96.png"
17+
"32": "src/icon.svg",
18+
"48": "src/icon.svg",
19+
"64": "src/icon.svg",
20+
"96": "src/icon.svg",
21+
"128": "src/icon.svg"
1922
},
2023
"browser_action": {
2124
"default_title": "NoteKeeper",
2225
"default_icon": {
23-
"48": "src/icons/icon48.png",
24-
"96": "src/icons/icon96.png"
26+
"32": "src/icon.svg",
27+
"48": "src/icon.svg",
28+
"64": "src/icon.svg",
29+
"96": "src/icon.svg",
30+
"128": "src/icon.svg"
2531
}
2632
},
2733
"sidebar_action": {
2834
"default_icon": {
29-
"48": "src/icons/icon48.png",
30-
"96": "src/icons/icon96.png"
35+
"32": "src/icon.svg",
36+
"48": "src/icon.svg",
37+
"64": "src/icon.svg",
38+
"96": "src/icon.svg",
39+
"128": "src/icon.svg"
3140
},
3241
"default_title": "NoteKeeper",
3342
"default_panel": "src/sidebar/panel.html"
File renamed without changes.

src/icon.svg

Lines changed: 19 additions & 0 deletions
Loading

src/script.js

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
const els = {
2+
html: document.documentElement,
3+
note: document.getElementById("notes"),
4+
toggleTheme: document.getElementById("theme-toggle"),
5+
toggleSettings: document.getElementById("settings-toggle"),
6+
menu: document.getElementById("settings-menu"),
7+
slider: document.getElementById("font-slider"),
8+
fontDisplay: document.getElementById("font-display"),
9+
words: document.getElementById("word-count"),
10+
status: document.getElementById("save-status"),
11+
};
12+
13+
// Storage Wrapper
14+
const store = {
15+
get: (k) => {
16+
try {
17+
return localStorage.getItem(k);
18+
} catch (e) {}
19+
},
20+
set: (k, v) => {
21+
try {
22+
localStorage.setItem(k, v);
23+
} catch (e) {}
24+
},
25+
};
26+
27+
// Theme Logic
28+
const toggleTheme = () => {
29+
const next =
30+
els.html.getAttribute("data-theme") === "dark" ? "light" : "dark";
31+
els.html.setAttribute("data-theme", next);
32+
store.set("theme", next);
33+
els.toggleTheme.setAttribute(
34+
"aria-label",
35+
`Switch to ${next === "dark" ? "light" : "dark"}`
36+
);
37+
};
38+
39+
els.toggleTheme.addEventListener("click", toggleTheme);
40+
41+
// Settings & Menu Logic
42+
const toggleMenu = (e) => {
43+
e.stopPropagation();
44+
const isHidden = els.menu.hidden;
45+
els.menu.hidden = !isHidden;
46+
els.toggleSettings.setAttribute("aria-expanded", !isHidden);
47+
};
48+
49+
const updateFontSize = (val) => {
50+
const size = `${val}px`;
51+
els.html.style.setProperty("--note-size", size);
52+
els.fontDisplay.textContent = size;
53+
store.set("fontsize", size);
54+
};
55+
56+
// Menu Listeners
57+
els.toggleSettings.addEventListener("click", toggleMenu);
58+
59+
els.slider.addEventListener("input", (e) => {
60+
updateFontSize(e.target.value);
61+
});
62+
63+
// Close menu when clicking outside
64+
document.addEventListener("click", (e) => {
65+
if (
66+
!els.menu.hidden &&
67+
!els.menu.contains(e.target) &&
68+
e.target !== els.toggleSettings
69+
) {
70+
els.menu.hidden = true;
71+
els.toggleSettings.setAttribute("aria-expanded", "false");
72+
}
73+
});
74+
75+
// Stats Logic
76+
const updateStats = (text) => {
77+
const count = text.trim() ? text.trim().split(/\s+/).length : 0;
78+
els.words.textContent = `${count} word${count === 1 ? "" : "s"}`;
79+
};
80+
81+
// Save Logic (Debounced)
82+
let timeout;
83+
const save = (text) => {
84+
els.status.textContent = "Saving...";
85+
els.status.classList.remove("saved");
86+
clearTimeout(timeout);
87+
timeout = setTimeout(() => {
88+
store.set("notekeeper_content", text);
89+
els.status.textContent = "Saved";
90+
els.status.classList.add("saved");
91+
}, 500);
92+
};
93+
94+
// Migration Logic (Legacy Chrome Storage -> LocalStorage)
95+
const migrateFromExtension = () => {
96+
// If we already have data in the new system, do not overwrite
97+
if (store.get("notekeeper_content")) return;
98+
99+
// Detect extension environment
100+
const ext =
101+
typeof browser !== "undefined"
102+
? browser
103+
: typeof chrome !== "undefined"
104+
? chrome
105+
: null;
106+
107+
if (ext && ext.storage && ext.storage.sync) {
108+
ext.storage.sync.get(["tab_note"], (result) => {
109+
// Check if legacy data exists
110+
if (result && result.tab_note) {
111+
// Save to new storage
112+
store.set("notekeeper_content", result.tab_note);
113+
114+
// Update UI immediately
115+
els.note.value = result.tab_note;
116+
updateStats(result.tab_note);
117+
els.status.textContent = "Restored";
118+
els.status.classList.add("saved");
119+
}
120+
});
121+
}
122+
};
123+
124+
// Init Content
125+
const content = store.get("notekeeper_content");
126+
if (content) {
127+
els.note.value = content;
128+
updateStats(content);
129+
} else {
130+
// Only attempt migration if new storage is empty
131+
migrateFromExtension();
132+
}
133+
134+
// Init Font Size
135+
const storedFontSize = store.get("fontsize");
136+
if (storedFontSize) {
137+
const val = parseInt(storedFontSize);
138+
els.slider.value = val;
139+
updateFontSize(val);
140+
}
141+
142+
els.note.addEventListener("input", (e) => {
143+
updateStats(e.target.value);
144+
save(e.target.value);
145+
});

0 commit comments

Comments
 (0)