UUUM攻殻機動隊(エンジニアブログ)

UUUMのエンジニアによる技術ブログです

Electron で付箋紙ウィジェットを作る

この記事は、UUUM Advent Calendar 2018 6日目です。


エンジニアをしているナカハシ(@k_nakahashi)です。

付箋紙アプリ、自分に合ったものを使いたい(ので作りたい)

私は作業用のPCでは、デスクトップ上に付箋紙アプリを浮かべていることが多いです。ウィンドウっぽいものを起動せずに、とりあえずテキストを打てる領域があるって気軽でいいんですよね。

Macで仕事するようになってからは、デフォルトでインストールされているスティッキーズという付箋アプリを使っていました。

これでも全然良かったのですが、個人的に以下のように動作してくれるともっと効率的になるな、と感じるようになってきました。

  • 付箋に書いたらすぐに内容をファイルに保存してほしい。作業ログになって便利
  • ブラウザから貼り付けたときなどに書式がついてしまうのが邪魔。プレーンテキストのほうがいい((⌥⇧⌘ + V でそういった動作になるのですが面倒))

今回は前から興味があったElectronで、Macアプリとして開発してみることにしました。

最低限必要な機能を実装

付箋らしい見た目

テキストファイルと同期するなら、それこそテキストエディタを使えばいいわけで、やはり付箋らしい見た目が欲しい。作業のメインで利用するエディタやブラウザの脇に軽く置いて邪魔にならないようにしました。

実装方法

付箋に付き一つ、 BrowserWindow を開きます。

フレームの非表示や最大化ボタンなどの調整でシンプルなウィンドウにします。 setMenu() メソッドに null を渡すことで、メニューバーも非表示になります。

import electron from 'electron';
const BrowserWindow = electron.BrowserWindow;

function _open() {
  const window = new BrowserWindow({
    width: 200, height: 200, frame: false, show: false,
    fullscreen: false, minimizable: true, maximizable: false
  });

  window.loadURL(`file://${__dirname}/renderer/post.html`);
  window.setMenu(null);
}

BrowserWindow から読み込むビューは、以下のようにBootstrap や自分で書いた style.css で見た目を調整しています。また、 post.js 内に、付箋内のボタンや文字表示用のロジックを React で書いています。(今回は省略)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Electron Read Us</title>
    <link rel="stylesheet" href="bootstrap.min.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div id="container" class="fix-height"></div>

    <script src="./post.js"></script>
  </body>
</html>

こんな感じの見た目になっています↓ f:id:k_nakahashi:20181206142017j:plain

テキストファイルと付箋が連携

書く → 保存 をシームレスにやりたいなと考えました。

いちいち「保存」コマンドを実行したり、付箋を削除しようとしたときに「バックアップを取りますか?」とか聞かれないよう、既定の動作として勝手に所定のフォルダに移動するなどしたい。

今回は、1つの付箋を1つのファイルと同期する手法をとることにしました。付箋の内容が更新されると、リアルタイムでファイルの内容に反映させます。

実装方法

chokidar という npm パッケージを使うと、簡単にディレクトリ内にファイル変更を監視できます。これを使い、特定のディレクトリ内のテキストファイルをチェックし、画面上の付箋ファイルと内容を同期するようにしました。

下記のように、watch 対象のディレクトリを指定したあとのハンドルで add を指定することで、そのディレクトリにテキストファイルが作られた場合に特定の処理を実行するようにできます。

import electron from 'electron';
import chokidar from 'chokidar';

const app = electron.app;

app.on('ready', () => {
  _watcher = chokidar.watch(DIRECTORY, {ignoreInitial: true});
  _watcher.on('add', _open);
});

今回はさきほど作った _open メソッドを指定し、付箋ウィンドウを開いています。

こうしておくことで、付箋新規作成したい場合は、特定のディレクトリにテキストファイルを作成すればいいことになります。

続きはこちらで実装していますので、興味のある方はぜひ!*1

まとめ

UUUM Advent Calendar 2018 はまだまだ続きます。私ももうひと記事書きます!(ネタ。。。)

UUUMでは、とにかくコードを書きたい! という方を探しています。まずはお気軽に連絡してくださいね!

www.wantedly.com

www.wantedly.com

*1:実は初期開発はまあまあ以前に行って、開発合宿に行ったときにLPまで作ったのですが、今回続きを作ろうと思って中身を思い出したい気持ちでこの記事を書いています