Escher-js / SkimmedMilk

0 stars 0 forks source link

step3. Select-Branch PullDown #3

Open psmuler opened 1 year ago

psmuler commented 1 year ago

先ほど作りかけた、新しいブランチを作る処理を加えたプルダウンメニューですが、create new branch を選択しても何も表示されません。let inputDialog = new BrowserWindowなどを用いてカスタムでinputboxとOK,Cancelボタンを備えたダイアローグボックスを表示しましょう

psmuler commented 1 year ago

electronBrowserWindowを使ってカスタムのinputboxとOK, Cancelボタンを備えたダイアログボックスを表示するために、以下の手順でmain.jsrenderer.jsファイルを更新し、新しいHTMLファイルbranch_input.htmlを作成します。

  1. branch_input.htmlファイルを作成し、入力ボックスとOK, Cancelボタンを含めます。
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Branch Input</title>
    <style>
      body {
        text-align: center;
        padding: 20px;
      }
      input {
        width: 300px;
      }
    </style>
  </head>
  <body>
    <h1>New Branch</h1>
    <input id="branch-name" type="text" placeholder="Enter branch name" />
    <br />
    <button id="ok-btn">OK</button>
    <button id="cancel-btn">Cancel</button>
    <script src="renderer.js"></script>
  </body>
</html>
  1. main.jsファイルで、createBranchInputDialog関数を作成し、カスタムダイアログのBrowserWindowを作成します。また、ipcMainをインポートし、ダイアログからのイベントを処理できるようにします。
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');

// ... (他のコードは省略) ...

function createBranchInputDialog() {
  const inputDialog = new BrowserWindow({
    width: 400,
    height: 200,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
    },
  });

  inputDialog.loadFile(path.join(__dirname, 'branch_input.html'));
}

ipcMain.handle('show-branch-input-dialog', () => {
  createBranchInputDialog();
});

// ... (他のコードは省略) ...
  1. renderer.jsファイルで、プルダウンメニューの選択が変更されたときに、カスタムダイアログを表示するように更新します。また、新しいブランチ名を取得してブランチを作成する処理を追加します。

const { ipcRenderer } = require('electron');
const fs = require('fs');
const { exec } = require('child_process');

// ... (他のコードは省略) ...

branchSelect.addEventListener('change', () => {
  if (branchSelect.value === 'Create new branch') {
    ipcRenderer.invoke('show-branch-input-dialog');
    // プルダウンメニューの選択をリセット
    branchSelect.value = '';
  }
});

ipcRenderer.on('create-new-branch', (event, newBranchName) => {
  const folderPath = folderPathSpan.textContent;
  exec(`git -C "${folderPath}" checkout -b "${newBranchName.trim()}"`, (error, stdout, stderr) => {
    // ... (他のコードは省略) ...
  });
});

// ... (他のコードは省略) ...
psmuler commented 1 year ago

ipcRenderer.on('create-new-branch')の中身を詳細に書いてもらえますか

psmuler commented 1 year ago

ipcRenderer.on('create-new-branch')のイベントリスナー内で、新しいブランチを作成するためにgit checkout -bコマンドを実行します。作成されたブランチに切り替えることも含まれます。また、ブランチが作成された後、ブランチ一覧を更新するためにupdateBranchList()関数を呼び出します。

renderer.jsファイルのipcRenderer.on('create-new-branch')イベントリスナーを以下のように更新します。

// ... (他のコードは省略) ...

ipcRenderer.on('create-new-branch', (event, newBranchName) => {
  const folderPath = folderPathSpan.textContent;

  // 新しいブランチを作成し、作成されたブランチに切り替える
  exec(`git -C "${folderPath}" checkout -b "${newBranchName.trim()}"`, (error, stdout, stderr) => {
    if (error) {
      console.error(`Error: ${error.message}`);
      return;
    }
    if (stderr) {
      console.error(`Stderr: ${stderr}`);
      return;
    }
    console.log(`Stdout: ${stdout}`);

    // ブランチ一覧を更新
    updateBranchList(folderPath);
  });
});

// ... (他のコードは省略) ...

この変更により、create-new-branchイベントがトリガーされたときに、新しいブランチを作成し、作成されたブランチに切り替えます。また、ブランチ作成後にブランチ一覧を更新します。

psmuler commented 1 year ago

ポップアップしたダイアログでOKボタンを押した時のイベントリスナを設定してください

psmuler commented 1 year ago

ポップアップしたダイアログでOKボタンを押したときのイベントリスナを設定するには、renderer.jsファイルに以下のコードを追加します。このコードは、branch_input.htmlファイルで読み込まれるため、同じrenderer.jsファイル内に追加することができます。

// ... (他のコードは省略) ...

if (document.getElementById('branch-input')) {
  const okBtn = document.getElementById('ok-btn');
  const cancelBtn = document.getElementById('cancel-btn');
  const branchNameInput = document.getElementById('branch-name');

  okBtn.addEventListener('click', () => {
    const newBranchName = branchNameInput.value;
    if (newBranchName.trim() === '') {
      alert('Branch name cannot be empty');
      return;
    }
    ipcRenderer.send('create-new-branch', newBranchName);
    window.close();
  });

  cancelBtn.addEventListener('click', () => {
    window.close();
  });
}

// ... (他のコードは省略) ...

このコードは、OKボタンがクリックされたときに、入力されたブランチ名を検証し、新しいブランチ名としてメインプロセスに送信します。また、キャンセルボタンがクリックされたときにダイアログを閉じます。

注意: 上記のコードは、renderer.jsファイルの他の部分と同じファイルに配置されていますが、if (document.getElementById('branch-input'))条件により、branch_input.htmlページでのみ実行されます。これは、他のページではbranch-input要素が存在しないためです。

psmuler commented 1 year ago

他のダイアログボックスなどで変数の汚染があるといけませんから、新しいjsファイルに書き込んだほうがいいのではないでしょうか

psmuler commented 1 year ago

おっしゃる通りです。新しいJavaScriptファイルを作成して、ダイアログボックス専用のコードをそこに移動することで、変数の汚染を防ぐことができます。以下の手順に従って、新しいファイルbranch_input_renderer.jsを作成しましょう。

  1. branch_input_renderer.jsという新しいファイルを作成します。

  2. renderer.jsファイルから、ダイアログボックスのイベントリスナに関連するコードをbranch_input_renderer.jsファイルに移動します。

branch_input_renderer.js:

const { ipcRenderer } = require('electron');

const okBtn = document.getElementById('ok-btn');
const cancelBtn = document.getElementById('cancel-btn');
const branchNameInput = document.getElementById('branch-name');

okBtn.addEventListener('click', () => {
  const newBranchName = branchNameInput.value;
  if (newBranchName.trim() === '') {
    alert('Branch name cannot be empty');
    return;
  }
  ipcRenderer.send('create-new-branch', newBranchName);
  window.close();
});

cancelBtn.addEventListener('click', () => {
  window.close();
});
  1. branch_input.htmlファイルで、新しく作成したbranch_input_renderer.jsファイルを読み込むように変更します。

branch_input.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Branch Input</title>
    <style>
      body {
        text-align: center;
        padding: 20px;
      }
      input {
        width: 300px;
      }
    </style>
  </head>
  <body>
    <h1>New Branch</h1>
    <input id="branch-name" type="text" placeholder="Enter branch name" />
    <br />
    <button id="ok-btn">OK</button>
    <button id="cancel-btn">Cancel</button>
    <script src="branch_input_renderer.js"></script>
  </body>
</html>

これで、新しいブランチの作成に関する処理がbranch_input_renderer.jsに移動され、他のコードとの変数の汚染を防ぐことができます。

psmuler commented 1 year ago

branch_input_renderer がipcRenderer.sendを実行していますが、renderer.jsと通信できるのでしょうか

psmuler commented 1 year ago

はい、branch_input_renderer.jsからrenderer.jsと通信できます。Electronアプリケーションでは、ipcRendereripcMainを使って異なるプロセス間でメッセージをやり取りすることができます。branch_input_renderer.jsからrenderer.jsへの通信は、ipcRendererからipcMainへの通信となり、ipcMainrenderer.jsにメッセージを転送します。

この場合、branch_input_renderer.jsipcRenderer.send('create-new-branch', newBranchName);を使ってcreate-new-branchイベントを送信します。このイベントは、main.jsファイルのipcMainによって受信され、main.jsrenderer.jsにイベントを転送します。

main.jsファイルで、以下のようにbranch_inputウィンドウとmainWindow間でイベントをリレーすることができます。

// ... (他のコードは省略) ...

ipcMain.on('create-new-branch', (event, newBranchName) => {
  mainWindow.webContents.send('create-new-branch', newBranchName);
});

// ... (他のコードは省略) ...

renderer.jsファイルでは、ipcRenderer.on('create-new-branch')イベントリスナーを追加して、main.jsからのイベントを受信し、適切な処理を実行します。

// ... (他のコードは省略) ...

ipcRenderer.on('create-new-branch', (event, newBranchName) => {
  const folderPath = folderPathSpan.textContent;

  // 新しいブランチを作成し、作成されたブランチに切り替える
  exec(`git -C "${folderPath}" checkout -b "${newBranchName.trim()}"`, (error, stdout, stderr) => {
    if (error) {
      console.error(`Error: ${error.message}`);
      return;
    }
    if (stderr) {
      console.error(`Stderr: ${stderr}`);
      return;
    }
    console.log(`Stdout: ${stdout}`);

    // ブランチ一覧を更新
    updateBranchList(folderPath);
  });
});

// ... (他のコードは省略) ...

この方法で、branch_input_renderer.jsからrenderer.jsへの通信が可能になります。

psmuler commented 1 year ago

branchの作成はできましたが、renderer.js>ipcRenderer.on('create-new-branch')>exec(git -C...)内の Switched to a new branchがstderrとして認識され、updateBranchListが実行されずにreturnされてしまいます

psmuler commented 1 year ago

git checkout -b コマンドは、新しいブランチへ切り替えた際にメッセージを stderr に出力することがありますが、これはエラーではありません。そのため、stderr にメッセージが出力された場合でも、それがエラーであるかどうかをチェックする必要があります。

renderer.js 内の ipcRenderer.on('create-new-branch') イベントリスナーの処理を次のように修正して、stderr にメッセージがあってもエラーでなければ updateBranchList を実行するようにしましょう。

// ... (他のコードは省略) ...

ipcRenderer.on('create-new-branch', (event, newBranchName) => {
  const folderPath = folderPathSpan.textContent;

  // 新しいブランチを作成し、作成されたブランチに切り替える
  exec(`git -C "${folderPath}" checkout -b "${newBranchName.trim()}"`, (error, stdout, stderr) => {
    if (error) {
      console.error(`Error: ${error.message}`);
      return;
    }

    // エラーでない場合、stderr の内容を出力
    if (stderr) {
      console.log(`Info: ${stderr}`);
    }

    console.log(`Stdout: ${stdout}`);

    // ブランチ一覧を更新
    updateBranchList(folderPath);
  });
});

// ... (他のコードは省略) ...

この変更により、新しいブランチが作成された場合、updateBranchList が正常に実行されるようになります。ただし、stderr にエラーが出力された場合は、それがエラーであるかどうかを判断するために適切な処理を追加することが重要です。今回の場合、新しいブランチへの切り替えメッセージが stderr に出力されるだけなので、エラーとして扱わないように修正しました。