Skip to content

Commit 849dc1f

Browse files
committed
feat: add debug feature for calendar
1 parent fa9b21e commit 849dc1f

File tree

1 file changed

+205
-2
lines changed

1 file changed

+205
-2
lines changed

src/options.tsx

Lines changed: 205 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,23 @@
1-
import { useEffect, useState } from "react";
1+
import { useCallback, useEffect, useState } from "react";
22
import { createRoot } from "react-dom/client";
3-
import { Button } from "./components/Button";
43
import browser from "webextension-polyfill";
4+
import { Button } from "./components/Button";
5+
import { icsToJson } from "./utils/icsToJson";
6+
7+
interface CalendarEvent {
8+
summary: string;
9+
description: string | null;
10+
location: string | null;
11+
startDate: string;
12+
endDate: string;
13+
status: string;
14+
}
15+
16+
interface CalendarSource {
17+
url: string;
18+
cacheTimestamp: string;
19+
events: CalendarEvent[];
20+
}
521

622
function Options() {
723
const [calendarUrls, setCalendarUrls] = useState<string[]>([""]);
@@ -14,6 +30,9 @@ function Options() {
1430
"right-top" | "right-bottom" | "left-top" | "left-bottom"
1531
>("right-top");
1632
const [minimalMode, setMinimalMode] = useState(false);
33+
const [debugMode, setDebugMode] = useState(false);
34+
const [calendarData, setCalendarData] = useState<CalendarSource[]>([]);
35+
const [isLoading, setIsLoading] = useState(false);
1736

1837
useEffect(() => {
1938
// Listen for changes in storage
@@ -68,6 +87,7 @@ function Options() {
6887
"enforceWorkingHours",
6988
"buttonPosition",
7089
"minimalMode",
90+
"icsCache",
7191
]);
7292

7393
if (result.calendarUrls) {
@@ -146,6 +166,75 @@ function Options() {
146166
});
147167
};
148168

169+
const loadCalendarData = useCallback(async () => {
170+
console.log("Loading calendar data...");
171+
setIsLoading(true);
172+
try {
173+
const { icsCache } = await browser.storage.local.get("icsCache");
174+
console.log("Retrieved icsCache:", icsCache);
175+
176+
if (!icsCache) {
177+
console.log("No icsCache found, setting empty data");
178+
setCalendarData([]);
179+
return;
180+
}
181+
182+
const allEvents: CalendarSource[] = [];
183+
184+
for (const [url, cacheData] of Object.entries(icsCache)) {
185+
const cache = cacheData as { data: string; timestamp: number };
186+
try {
187+
const events = icsToJson(cache.data);
188+
console.log(`Parsed ${events.length} events for ${url}`);
189+
allEvents.push({
190+
url,
191+
cacheTimestamp: new Date(cache.timestamp).toLocaleString(),
192+
events,
193+
});
194+
} catch (error) {
195+
console.error(`Error parsing ICS data for ${url}:`, error);
196+
}
197+
}
198+
199+
console.log("Setting calendar data:", allEvents);
200+
setCalendarData(allEvents);
201+
} catch (error) {
202+
console.error("Error loading calendar data:", error);
203+
alert(`Error loading calendar data: ${error}`);
204+
} finally {
205+
setIsLoading(false);
206+
}
207+
}, []);
208+
209+
// watch icsCache changes in real-time
210+
useEffect(() => {
211+
if (!debugMode) return;
212+
213+
const handleIcsCacheChange = (
214+
changes: { [key: string]: browser.Storage.StorageChange },
215+
areaName: string
216+
) => {
217+
if (areaName !== "local") return;
218+
219+
if (changes.icsCache) {
220+
loadCalendarData();
221+
}
222+
};
223+
224+
browser.storage.onChanged.addListener(handleIcsCacheChange);
225+
226+
// when debug mode is enabled, load the initial data
227+
loadCalendarData();
228+
229+
return () => {
230+
browser.storage.onChanged.removeListener(handleIcsCacheChange);
231+
};
232+
}, [debugMode, loadCalendarData]);
233+
234+
const handleDebugToggle = () => {
235+
setDebugMode(!debugMode);
236+
};
237+
149238
return (
150239
<div style={{ padding: "20px", maxWidth: "600px", margin: "0 auto" }}>
151240
<h1>Google Calendar Tonton - Settings</h1>
@@ -351,6 +440,120 @@ function Options() {
351440
Use minimal button mode (icon only)
352441
</label>
353442
</div>
443+
<div style={{ marginBottom: "20px" }}>
444+
<label style={{ display: "flex", alignItems: "center", gap: "8px" }}>
445+
<input
446+
type="checkbox"
447+
checked={debugMode}
448+
onChange={handleDebugToggle}
449+
/>
450+
Debug Mode (Show Calendar Data)
451+
</label>
452+
</div>
453+
{debugMode && (
454+
<div style={{ marginBottom: "20px" }}>
455+
<h2>Calendar Debug Information</h2>
456+
<div style={{ marginBottom: "16px" }}>
457+
<button
458+
type="button"
459+
onClick={() => {
460+
console.log("Refresh button clicked");
461+
loadCalendarData();
462+
}}
463+
disabled={isLoading}
464+
style={{
465+
marginRight: "10px",
466+
padding: "8px 16px",
467+
borderRadius: "4px",
468+
border: "1px solid #ccc",
469+
background: isLoading ? "#e0e0e0" : "#f5f5f5",
470+
cursor: isLoading ? "not-allowed" : "pointer",
471+
opacity: isLoading ? 0.6 : 1,
472+
}}
473+
>
474+
{isLoading ? "Loading..." : "Refresh Calendar Data"}
475+
</button>
476+
<span style={{ fontSize: "12px", color: "#666" }}>
477+
{isLoading
478+
? "Updating..."
479+
: `Last updated: ${new Date().toLocaleTimeString()}`}
480+
</span>
481+
</div>
482+
{calendarData.length === 0 ? (
483+
<p>No calendar data found in cache.</p>
484+
) : (
485+
calendarData.map((calendarSource) => (
486+
<div
487+
key={calendarSource.url}
488+
style={{
489+
marginBottom: "24px",
490+
padding: "16px",
491+
border: "1px solid #ddd",
492+
borderRadius: "4px",
493+
background: "#f9f9f9",
494+
}}
495+
>
496+
<h3>Calendar Source</h3>
497+
<p style={{ overflowWrap: "anywhere" }}>
498+
<strong>URL:</strong> {calendarSource.url}
499+
</p>
500+
<p>
501+
<strong>Cache Updated:</strong>{" "}
502+
{calendarSource.cacheTimestamp}
503+
</p>
504+
<p>
505+
<strong>Events Found:</strong> {calendarSource.events.length}
506+
</p>
507+
508+
{calendarSource.events.length > 0 && (
509+
<div style={{ marginTop: "16px" }}>
510+
<h4>Events:</h4>
511+
<div style={{ maxHeight: "300px", overflowY: "auto" }}>
512+
{calendarSource.events.map((event) => (
513+
<div
514+
key={`${event.startDate}-${event.summary}`}
515+
style={{
516+
marginBottom: "12px",
517+
padding: "12px",
518+
border: "1px solid #ccc",
519+
borderRadius: "4px",
520+
background: "#fff",
521+
}}
522+
>
523+
<p>
524+
<strong>Title:</strong> {event.summary}
525+
</p>
526+
<p>
527+
<strong>Start:</strong>{" "}
528+
{new Date(event.startDate).toLocaleString()}
529+
</p>
530+
<p>
531+
<strong>End:</strong>{" "}
532+
{new Date(event.endDate).toLocaleString()}
533+
</p>
534+
<p>
535+
<strong>Status:</strong> {event.status}
536+
</p>
537+
{event.location && (
538+
<p>
539+
<strong>Location:</strong> {event.location}
540+
</p>
541+
)}
542+
{event.description && (
543+
<p>
544+
<strong>Description:</strong> {event.description}
545+
</p>
546+
)}
547+
</div>
548+
))}
549+
</div>
550+
</div>
551+
)}
552+
</div>
553+
))
554+
)}
555+
</div>
556+
)}
354557
<div style={{ display: "flex", alignItems: "center" }}>
355558
<Button onClick={handleSave} variant="other">
356559
Save

0 commit comments

Comments
 (0)