PageSourceSearch

https://haiphen.io/components/welcome-overlay/welcome-overlay.js

js haiphen.io collected 2026-10-01 12:02:43 UTC 3,452 bytes, 118 lines download raw bytes

1(function () {
2  'use strict';
3
4  const NS = (window.HAIPHEN = window.HAIPHEN || {});
5  const STORAGE_KEY = 'haiphen.welcome_seen';
6
7  // Capture session early (before async template fetch)
8  let _sessionUser = undefined; // undefined = not yet received
9  window.addEventListener('haiphen:session:ready', (e) => {
10    _sessionUser = e.detail?.user || null;
11  }, { once: true });
12
13  function injectCssOnce(href) {
14    if (document.querySelector(`link[rel="stylesheet"][href="${href}"]`)) return;
15    const link = document.createElement('link');
16    link.rel = 'stylesheet';
17    link.href = href;
18    document.head.appendChild(link);
19  }
20
21  async function fetchText(url) {
22    const r = await fetch(url, { cache: 'no-store' });
23    if (!r.ok) throw new Error(`HTTP ${r.status}`);
24    return r.text();
25  }
26
27  function alreadySeen() {
28    try { return !!localStorage.getItem(STORAGE_KEY); } catch { return false; }
29  }
30
31  function markSeen() {
32    try { localStorage.setItem(STORAGE_KEY, new Date().toISOString()); } catch { /* noop */ }
33  }
34
35  NS.WelcomeOverlay = {
36    async init(mountSelector) {
37      if (alreadySeen()) return;
38
39      const mount = document.querySelector(mountSelector);
40      if (!mount) return;
41
42      injectCssOnce('components/welcome-overlay/welcome-overlay.css');
43
44      try {
45        const html = await fetchText('components/welcome-overlay/welcome-overlay.html');
46        mount.innerHTML = html;
47      } catch (e) {
48        console.warn('[welcome-overlay] failed to load template', e);
49        return;
50      }
51
52      const backdrop = mount.querySelector('[data-welcome-overlay]');
53      if (!backdrop) return;
54
55      function show() {
56        setTimeout(() => {
57          backdrop.classList.add('is-visible');
58        }, 600);
59      }
60
61      // Session may have already fired before template loaded
62      if (_sessionUser !== undefined) {
63        if (_sessionUser) show();
64      } else {
65        // Still waiting — listen again
66        window.addEventListener('haiphen:session:ready', (e) => {
67          if (e.detail?.user) show();
68        }, { once: true });
69      }
70
71      // Also check if session pill already exists (logged in)
72      if (_sessionUser === undefined && document.querySelector('.session-pill')) {
73        show();
74      }
75
76      // Wire buttons
77      backdrop.addEventListener('click', (e) => {
78        const action = e.target.closest('[data-welcome-action]');
79        if (!action) {
80          if (e.target === backdrop) dismiss();
81          return;
82        }
83
84        const act = action.getAttribute('data-welcome-action');
85        if (act === 'explore') {
86          markSeen();
87          hide();
88          if (typeof window.navigateTo === 'function') {
89            window.navigateTo('GettingStarted');
90          } else if (typeof window.showSection === 'function') {
91            window.showSection('GettingStarted');
92            window.location.hash = '#getting-started';
93          }
94        } else if (act === 'dismiss') {
95          dismiss();
96        }
97      });
98
99      function dismiss() {
100        markSeen();
101        hide();
102      }
103
104      function hide() {
105        backdrop.classList.remove('is-visible');
106        setTimeout(() => { mount.innerHTML = ''; }, 400);
107      }
108
109      const onKey = (e) => {
110        if (e.key === 'Escape') {
111          dismiss();
112          document.removeEventListener('keydown', onKey);
113        }
114      };
115      document.addEventListener('keydown', onKey);
116    }
117  };
118})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.