Mercurial
annotate mrjunejune/src/index.js @ 279:b3b547563ec7
Add Google connector service and agent wiki
Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code.
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 17 Aug 2026 22:22:36 -0700 |
| parents | 60a876c4587a |
| children |
| rev | line source |
|---|---|
| 82 | 1 const THEME_STORAGE_KEY = 'theme-preference'; |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
2 const THEMES = ['auto', 'paper', 'ink', 'playful']; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
3 const THEME_LABELS = { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
4 auto: 'Auto', |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
5 paper: 'Paper', |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
6 ink: 'Ink', |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
7 playful: 'Playful', |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
8 }; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
9 |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
10 function normalizeTheme(value) { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
11 if (value === 'light') return 'paper'; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
12 if (value === 'dark') return 'ink'; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
13 return THEMES.includes(value) ? value : 'auto'; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
14 } |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
15 |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
16 function getThemePreference() { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
17 return normalizeTheme(localStorage.getItem(THEME_STORAGE_KEY)); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
18 } |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
19 |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
20 function updateThemeColor() { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
21 const probe = document.createElement('span'); |
|
258
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
22 probe.style.background = 'var(--zenbu-sys-color-surface-page)'; |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
23 document.body.append(probe); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
24 const color = getComputedStyle(probe).backgroundColor; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
25 probe.remove(); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
26 document.querySelector('meta[name="theme-color"]') |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
27 ?.setAttribute('content', color); |
|
76
35b1abc37969
Updating my website to use seobeo library.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
28 } |
|
35b1abc37969
Updating my website to use seobeo library.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
29 |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
30 function updateThemeControl(preference) { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
31 const toggle = document.querySelector('#themeToggle'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
32 const label = document.querySelector('#themeName'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
33 if (label) label.textContent = THEME_LABELS[preference]; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
34 toggle?.setAttribute( |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
35 'aria-label', |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
36 `Change site theme. Current theme: ${THEME_LABELS[preference]}`, |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
37 ); |
|
76
35b1abc37969
Updating my website to use seobeo library.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
38 } |
|
35b1abc37969
Updating my website to use seobeo library.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
39 |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
40 function applyTheme(value, persist = false) { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
41 const preference = normalizeTheme(value); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
42 const root = document.documentElement; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
43 root.classList.remove('light-mode', 'dark', 'auto'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
44 if (preference === 'auto') delete root.dataset.zenTheme; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
45 else root.dataset.zenTheme = preference; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
46 if (persist) localStorage.setItem(THEME_STORAGE_KEY, preference); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
47 updateThemeControl(preference); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
48 requestAnimationFrame(updateThemeColor); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
49 document.dispatchEvent(new CustomEvent('zen-theme-change', { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
50 detail: { theme: preference }, |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
51 })); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
52 return preference; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
53 } |
|
80
d55157451947
[MrJuneJune] Updating my homepage.
June Park <parkjune1995@gmail.com>
parents:
76
diff
changeset
|
54 |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
55 const currentPreference = applyTheme(getThemePreference()); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
56 if (localStorage.getItem(THEME_STORAGE_KEY) !== currentPreference) { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
57 localStorage.setItem(THEME_STORAGE_KEY, currentPreference); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
58 } |
|
80
d55157451947
[MrJuneJune] Updating my homepage.
June Park <parkjune1995@gmail.com>
parents:
76
diff
changeset
|
59 |
|
258
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
60 function enhanceLinks(root = document) { |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
61 const links = root instanceof HTMLAnchorElement |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
62 ? [root] |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
63 : [...root.querySelectorAll?.('a') || []]; |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
64 for (const link of links) { |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
65 if (link.closest('zen-link, zen-button') || |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
66 link.dataset.zenLinkEffect === 'none') { |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
67 continue; |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
68 } |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
69 const wrapper = document.createElement('zen-link'); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
70 wrapper.setAttribute('effect', 'paw'); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
71 link.before(wrapper); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
72 wrapper.append(link); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
73 } |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
74 } |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
75 |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
76 window.addEventListener('DOMContentLoaded', () => { |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
77 enhanceLinks(); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
78 const observer = new MutationObserver(records => { |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
79 for (const record of records) { |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
80 for (const node of record.addedNodes) { |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
81 if (node instanceof Element) enhanceLinks(node); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
82 } |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
83 } |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
84 }); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
85 observer.observe(document.body, { childList: true, subtree: true }); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
86 }); |
|
60a876c4587a
[ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents:
256
diff
changeset
|
87 |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
88 document.querySelector('#themeToggle')?.addEventListener('click', () => { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
89 const current = getThemePreference(); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
90 const next = THEMES[(THEMES.indexOf(current) + 1) % THEMES.length]; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
91 applyTheme(next, true); |
|
80
d55157451947
[MrJuneJune] Updating my homepage.
June Park <parkjune1995@gmail.com>
parents:
76
diff
changeset
|
92 }); |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
93 |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
94 matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
95 if (getThemePreference() === 'auto') updateThemeColor(); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
96 }); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
97 |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
98 window.MrJuneJuneTheme = Object.freeze({ |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
99 apply: theme => applyTheme(theme, true), |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
100 current: getThemePreference, |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
101 themes: [...THEMES], |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
84
diff
changeset
|
102 }); |