Electron で Remotty のクライントアプリ作ってみた

僕らのチームではこの前の神山.rb(https://kamiyamarb.doorkeeper.jp/) をきっかけに知った Remotty を使ってみています。 リモートワーカーがいるチームとしてはすごく良いツールです。

ただ、Slack のように常時立ちあげて利用するほど重宝しているツールであるため、 僕個人の使い方的に、ブラウザの 1 タブとして立ち上げるのではなく、クライアントアプリみたいな感じに利用したいと思いました。

そこで、最近興味を持っていた Electron で簡単なクライアントアプリを作ってみました。 作ってみたアプリは https://github.com/yonda/electron-remotty で公開しています。

前提

node は npm は入っていること。

導入

以下のコマンドで Electron をインストールします。

$ npm -g install electron-prebuilt

で、プロジェクト用のディレクトリをきって、npm init

$ mkdir electron-remotty
$ cd electron-remotty
$ npm init -y

package.json の main は main.js としておきます。

main.js の実装

まずは https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md 通りに main.js を作っていきます。

'use strict';

var app = require('app');
var BrowserWindow = require('browser-window');

require('crash-reporter').start();

var mainWindow = null;

app.on('window-all-closed', function () {
  if (process.platform != 'darwin') {
    app.quit();
  }
});

app.on('ready', function () {
  mainWindow = new BrowserWindow({width: 1280, height: 800});

  mainWindow.loadUrl('file://' + __dirname + '/index.html');
  mainWindow.on('closed', function () {
    mainWindow = null;
  });
});

僕は MacBookPro の 13 inch をつかっていて、ウィンドウサイズはフルサイズで起動したかったので width と height だけ少し変えています。

index.html の実装

ここは Quick Start とは少し変えていて、webview で remotty を表示するようにしています。 また、style タグで webview のサイズをウィンドウサイズに合わせるようにしています。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>remotty</title>
  </head>
  <body>
    <script>console.log("Hello World");</script>
    <webview id="mainWebview" 
      src="https://www.remotty.net" autosize="on"></webview>
    <style>
       webview {
         position: absolute;
         top: 0;
         right: 0;
         bottom: 0;
         left: 0;
       }
     </style>
  </body>
</html>

<script>console.log("Hello World");</script> という変な記述がありますが、これは後ほど説明します。

起動

あとは起動するだけで、一通り完成です。

$ electron .

すごく簡単。デスクトップ通知もこれだけで出てくれます。

ハマった点

ここはちょっと良くわかっていないのですが、何故か webview を追加しただけだと何も表示されませんでした。 調べてみると、何かしら script タグがないと動いてくれないらしい。 ので、何かしら script が必要になるまでは <script>console.log("Hello World");</script> みたいに適当な script を突っ込んでおきました。

参考

http://qiita.com/yoching/items/b1eba88f75320a61bcc6 https://github.com/atom/electron/issues/1117

いろいろ便利にしたこと

コピペやリロードができるようにした

このままではコピペやリロードは出来ないので、https://github.com/atom/electron/blob/master/docs/api/menu.md を参考に、コンテキストメニューを追加しました。 (追加した、というより会社の後輩に PR もらった。感謝。)

main.js

app.on('ready', function () {
  // 省略
  setApplicationMenu();
}

function setApplicationMenu (){
  var Menu = require('menu');
  var menu = Menu.buildFromTemplate([
    {
      label: "Application",
      submenu: [
        {label: "About Application", selector: "orderFrontStandardAboutPanel:"},
        {type: "separator"},
        {label: "Quit", accelerator: "Command+Q", click: function() { app.quit(); }}
      ]
    },
    {
      label: "View",
      submenu: [
        {
          label: 'Reload',
          accelerator: 'CmdOrCtrl+R',
          click: function(item, focusedWindow) {
            if (focusedWindow)
              focusedWindow.reload();
          }
        },
      ]
    },
    {
      label: "Edit",
      submenu: [
        { label: "Undo", accelerator: "Command+Z", selector: "undo:" },
        { label: "Redo", accelerator: "Shift+Command+Z", selector: "redo:" },
        { type: "separator" },
        { label: "Cut", accelerator: "Command+X", selector: "cut:" },
        { label: "Copy", accelerator: "Command+C", selector: "copy:" },
        { label: "Paste", accelerator: "Command+V", selector: "paste:" }
      ]
    }
  ]);
  Menu.setApplicationMenu(menu);
}

これでコピペやリロードができるようになりました。

リンクをクリックしたらデフォルトブラウザで開くようにした

このままでは外部リンクが開けなかったので、https://github.com/atom/electron/blob/master/docs/api/web-view-tag.md を見つつ対応してみました。

index.html

<script>
onload = function() {
  var webview = document.getElementById("mainWebview");

  webview.addEventListener('new-window', function(e) {
    require('shell').openExternal(e.url);
  });
}
</script>

使ってみての感想

Electron すごく便利。今回みたいな WebView 貼るだけだったらほんと 30 分あればできるし、ここからクライアントアプリっぽくいろいろカスタマイズも出来そう。いろいろ試してみたい。