本アプリはシステム設計・設計パターン学習用のWindowsデスクトップ向けランチャーアプリです。
フレームワーク(React/Vue等)は一切使用せず、素のJavaScriptで「コンポーネント管理」「基底クラス継承構造」「設計パターン」を学ぶことを目的とします。
学習教材・サンプル実装として、拡張性・保守性・設計パターンの理解を重視します。
コンポーネント名 | 役割 |
---|---|
BaseManager | すべてのマネージャーの基底クラス。共通の初期化・データ管理・エラーハンドリング等を定義。各マネージャーはこれを継承し、共通ルールに従う。 |
LauncherManager | ランチャー項目のCRUD・起動管理(BaseManagerを継承) |
GroupManager | グループ(カテゴリ)管理(BaseManagerを継承) |
UsageHistoryManager | 履歴記録・集計(BaseManagerを継承) |
PluginManager | プラグインの検出・登録(BaseManagerを継承) |
UIStateManager | UI状態(テーマ・画面等)の管理(BaseManagerを継承) |
SecurityManager | 外部起動警告・データ暗号化等(BaseManagerを継承) |
コンポーネント名 | 役割・特徴(API経由でデータ取得・操作依頼) |
---|---|
BaseComponent | すべてのUIコンポーネントの基底クラス。共通のライフサイクル・バリデーション・イベントハンドラ等を定義。各UIコンポーネントはこれを継承。 |
LauncherList | ランチャーアイテムの一覧表示・操作(BaseComponentを継承) |
LauncherItem | 個別アイテムの表示・操作(BaseComponentを継承) |
GroupTabs | グループ切り替えUI(BaseComponentを継承) |
SearchBar | 検索・フィルタ入力(BaseComponentを継承) |
SettingsPanel | 設定画面(BaseComponentを継承) |
EditDialog | アイテム編集・新規登録ダイアログ(BaseComponentを継承) |
ThemeProvider | テーマ管理(BaseComponentを継承) |
AppShell | 全体レイアウト・UI構成管理(BaseComponentを継承)。 すべてのUIコンポーネント(DropZone, LauncherList等)の登録・生成・ライフサイクル管理を一元的に行う親コンポーネント。 新しいUI部品もAppShellに登録するだけで全体管理下に組み込める。 |
DropZone | ドラッグ&ドロップでWindowsアプリ(.lnk, .exe)を登録する専用コンポーネント。 ドロップされたファイルがアプリ(.lnk, .exe)かどうかを判定し、必要な情報(パス、名前、アイコン等)を抽出してランチャーに登録する。 ファイルパスの取得には、ElectronのwebUtils API(IPC経由)を利用する。 (セキュリティ上、レンダラープロセスから直接ファイルパスを取得せず、preloadスクリプトやIPC経由でメインプロセスに処理を依頼する設計とする) |
StartPilot/
src/
main/
managers/
baseManager.js
launcherManager.js
groupManager.js
usageHistoryManager.js
pluginManager.js
uiStateManager.js
securityManager.js
data/
launcher_items.json
usage_history.json
groups.json
plugins/
renderer/
components/
BaseComponent.js
LauncherList.js
LauncherItem.js
GroupTabs.js
SearchBar.js
SettingsPanel.js
EditDialog.js
ThemeProvider.js
AppShell.js
DropZone.js
locales/
ja.json
en.json
index.html
index.js
package.json
...
{
"id": "uuid",
"name": "MyApp",
"type": "app",
"path": "C:\\Program Files\\MyApp\\MyApp.exe",
"args": ["--mode", "debug"],
"icon": "myapp.png",
"group": "業務",
"tags": ["業務", "カスタム"],
"lastUsed": "2024-06-01T12:34:56Z",
"useCount": 42
}
※ ドラッグ&ドロップで登録した場合、pathやname、iconは自動取得される。
{
"id": "uuid",
"name": "開発"
}
{
"timestamp": "2024-06-01T12:34:56Z",
"action": "launch",
"target": "C:\\Program Files\\Microsoft VS Code\\Code.exe"
}
メソッド | 機能 | パラメータ例 |
---|---|---|
getItems() | ランチャー一覧取得 | |
addItem(item) | ランチャー追加 | { name, type, ... } |
editItem(id, item) | ランチャー編集 | { ... } |
deleteItem(id) | ランチャー削除 | |
launchItem(id) | ランチャー起動 | |
getGroups() | グループ一覧取得 | |
setTheme(theme) | テーマ切り替え | "dark"等 |
AppShell(画面全体の親)
├─ GroupTabs
├─ SearchBar
├─ LauncherList
│ ├─ LauncherItem
│ ├─ LauncherItem
│ └─ ...
├─ SettingsPanel
├─ EditDialog
├─ DropZone(ここに.lnkや.exeをドラッグ&ドロップで登録)
└─ ...他の部品
DropZoneに.lnkや.exeファイルをドラッグ&ドロップすることで、アプリ登録が直感的に行える。
ファイルパスの取得はwebUtils API(IPC経由)で行い、セキュリティを確保する。
// preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
getDroppedFiles: (event) => ipcRenderer.invoke('webUtils.getDroppedFiles', event)
});
// DropZone.js(レンダラー側)
this.root.ondrop = async (e) => {
e.preventDefault();
const files = await window.electronAPI.getDroppedFiles(e);
// files配列から.lnkや.exeを判定・登録
};
// baseManager.js
function BaseManager() {}
BaseManager.prototype.init = function() { /* ... */ };
BaseManager.prototype.save = function() { /* ... */ };
BaseManager.prototype.load = function() { /* ... */ };
BaseManager.prototype.handleError = function(err) { /* ... */ };
// ...
module.exports = BaseManager;
// サブクラス例
const BaseManager = require('./baseManager');
function LauncherManager() { BaseManager.call(this); }
LauncherManager.prototype = Object.create(BaseManager.prototype);
// ...
// BaseComponent.js
function BaseComponent(rootElement) {
this.root = rootElement;
}
BaseComponent.prototype.render = function() { /* ... */ };
BaseComponent.prototype.bindEvents = function() { /* ... */ };
BaseComponent.prototype.validate = function() { /* ... */ };
// ...
// サブクラス例
function LauncherList(rootElement) {
BaseComponent.call(this, rootElement);
}
LauncherList.prototype = Object.create(BaseComponent.prototype);
LauncherList.prototype.render = function() {
// ...
};
<body>
<div id="app"></div> <!-- index.htmlで提供 -->
</body>
// ...
// AppShellや各コンポーネントがこの中に独自のUIタグを描画
<div class="launcher-list">
</div>
<div class="drop-zone" ondrop="...">
ここにアプリやファイルをドロップ
</div>
<form class="settings-panel">
<label>テーマ<select ...>...</select></label>
...
</form>
この設計により、各コンポーネントは独自のUI表示・HTMLタグ構造を持ち、index.htmlは全体の箱として機能する。UIの拡張やカスタマイズも容易。