Newer
Older
TelosDB / src / frontend / components / main-panel.js
import { loadSettingsFromFile, SETTINGS_KEY, DEFAULTS } from '../js/shared.js';

class MainPanel extends HTMLElement {
  connectedCallback() {
    if (this._initialized) return;
    this._initialized = true;
    this.className = 'main-panel';
    // F5/WebView でスクリプト実行順がずれても子パネルが未定義だと中身が真っ黒になるため、
    // 先に子コンポーネントを import してから DOM を挿入する。
    (async () => {
      try {
        await Promise.all([
          import('./search-panel.js'),
          import('./docs-panel.js'),
          import('./settings-panel.js'),
        ]);
      } catch (e) {
        console.error('[MainPanel] panel imports failed:', e);
        this.innerHTML = `
          <div id="panel-settings" class="panel">
            <h2>設定</h2>
            <p class="settings-feedback">パネルの読み込みに失敗しました。F5 で再読み込みするかコンソールを確認してください。</p>
          </div>
        `;
        return;
      }
      try {
        // 先頭パネルだけ挿入。他は表示時に作成して汚い描画を防ぐ
        this.innerHTML = `
          <div class="main-panel-loading" aria-live="polite">読み込み中...</div>
          <div class="main-panel-content hidden">
            <search-panel id="panel-search" class="panel"></search-panel>
          </div>
        `;

        document.addEventListener('navigate-panel', (e) => {
          const target = String(e.detail || 'search');
          this.showPanel(target);
        });

        const contentEl = () => this.querySelector('.main-panel-content');

        this.showPanel = (panelId) => {
          const content = contentEl();
          const panels = content ? content.querySelectorAll('.panel') : [];
          panels.forEach((p) => p && p.classList.add('hidden'));
          let target = null;
          if (panelId === 'docs') {
            target = this.querySelector('#panel-docs');
            if (!target && content) {
              target = document.createElement('docs-panel');
              target.id = 'panel-docs';
              target.className = 'panel';
              content.appendChild(target);
            }
            if (target) {
              target.classList.remove('hidden');
              if (target.loadDocsList) target.loadDocsList();
            }
          } else if (panelId === 'settings') {
            target = this.querySelector('#panel-settings');
            if (!target && content) {
              target = document.createElement('settings-panel');
              target.id = 'panel-settings';
              target.className = 'panel';
              content.appendChild(target);
            }
            if (target) {
              target.classList.remove('hidden');
              // MCP 等で設定が変更されている可能性があるため、表示のたびにバックエンドから再取得する
              if (target.loadForm) target.loadForm();
            }
          } else {
            target = this.querySelector('#panel-search');
            if (target) {
              target.classList.remove('hidden');
              if (target.updateCategoryFilter) target.updateCategoryFilter();
            }
          }
        };

        // 読み込み中を出したままパネルを描画させ、少し待ってから本編に切り替える(描画途中を見せない)
        const loadingEl = this.querySelector('.main-panel-loading');
        const contentDiv = this.querySelector('.main-panel-content');
        const flipToContent = () => {
          if (loadingEl) loadingEl.remove();
          if (contentDiv) contentDiv.classList.remove('hidden');
        };
        requestAnimationFrame(() => requestAnimationFrame(() => setTimeout(flipToContent, 250)));

        (async () => {
          let fromFile = null;
          try {
            fromFile = await loadSettingsFromFile();
            this._initialSettings = fromFile;
          } catch (_) {
            console.warn('[TelosDB] 設定ファイル読み込み失敗 — autostart 同期をスキップ');
            this.showPanel('search');
            return;
          }
          try {
            const s = fromFile || (() => {
              const raw = localStorage.getItem(SETTINGS_KEY);
              return raw ? { ...DEFAULTS, ...JSON.parse(raw) } : DEFAULTS;
            })();
            const invoke = window.__TAURI__?.core?.invoke;
            if (invoke) {
              const enabled = await invoke('autostart_is_enabled');
              if (s.run_on_login && !enabled) {
                await invoke('autostart_enable');
                console.log('[TelosDB] autostart: 設定に合わせて有効化');
              } else if (!s.run_on_login && enabled) {
                await invoke('autostart_disable');
                console.log('[TelosDB] autostart: 設定に合わせて無効化');
              }
            }
          } catch (e) {
            console.error('[TelosDB] autostart 同期エラー:', e);
          }
          this.showPanel('search');
        })();
      } catch (err) {
        console.error('[MainPanel] init error:', err);
        this.innerHTML = `
          <div id="panel-search" class="panel"><div class="empty-state">検索</div></div>
          <div id="panel-docs" class="panel hidden"><div class="empty-state">文書管理</div></div>
          <div id="panel-settings" class="panel">
            <h2>設定</h2>
            <p class="settings-feedback">設定パネルの読み込みに失敗しました。コンソールを確認してください。</p>
          </div>
        `;
        this.querySelectorAll('.panel').forEach((p, i) => {
          if (i === 0) p.classList.remove('hidden');
        });
      }
    })();
  }
}

customElements.define('main-panel', MainPanel);
export {};