2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

何を作ったのか

まだプロトタイプの域を出ませんが、新しいドキュメント管理体験ができるデスクトップアプリを作りました。ixmaという名前がついています。100programという長期ハッカソンの成果物です。

メモにインデントを掘ると上位のインデントがタグとして機能し、関連するセクションを自動で整理して見返すことができます。

思想

このアプリは、(特にウェット系の)「研究ノート」をよりよく管理するために開発されました。
研究ノートは、実験の結果などを体系だって管理する必要がありますが、その見返し方はさまざまです。同じ試薬どうしで別の実験を比較することも、同じ実験手法どうしで別の試料を比較することもあります。

例えば以下のような階層でメモを管理している場合を考えます。

試料A
 ├ 実験A
 ├ 実験B
 └ 実験C
試料B
 ├ 実験A
 └ 実験B

このとき、試料A同士で実験A~Cの結果を一覧することは簡単ですが、実験Aの結果をさまざまな試料で比較した場合には少し不便です。

このアプリでは、先のデモ動画で示したように、タグをクリックすることで階層構造をその場で構築し直し、関連するセクションだけを抽出して一覧することができます。

他のドキュメント管理アプリとの比較

このアプリの開発にあたって、デジタルのドキュメント管理アプリの前例として「Notion」と「Scrapbox」を挙げました。

Notionは、階層管理に適したタスクと脳みそを持っている人々にとっては最高のアプリです。
しかし、「こうもり問題」が指摘するように、多くの人にとって秩序を持ったまま階層管理を続けることは苦行になり得ます。「こうもりを分類するのは、獣フォルダか?鳥フォルダか?」といった、階層型の管理が必ず直面する問題。どちらにも分類できるファイルたちについて、俺ルールによってカオスな分類が進んでいくことは想像に難くありません。

Scrapboxはこういったドキュメント管理の弱点を指摘し、階層を完全に撤廃して「リンク」を用いたネットワーキング型ドキュメント管理を提唱しました。それは素晴らしいもので、筆者も愛用しています。

しかし、「過去の記録を横断的に見返す」という点において、階層型が持っていたメリットは無視しきれませんでした。特に、雑多にメモを取りつつも、まとめる際には体系的に見返す必要がある実験化学の現場ではそれが顕著です。

求められているのは、「Scrapboxのように書けて、Notionのように見返せる」ドキュメント管理アプリだと感じ、それを目指して開発しています。

技術的な話

KMPを用いて、ほぼ全てのコードをKotlinで書いています。
KMPを採用した経緯は、元々ネイティブモバイルアプリを作ろうとしていて、KotlinやComposeを触ったことのある人々で開発チームを組んだのですが、ユーザーヒアリングを進めるにつれてデスクトップアプリの方が優先度が高いことが判明したため、モバイルと同じ感覚で書くことのできるCompose for Desktopを用いることを決断しました。

机の上に紙を広げていくような感覚でメモを見返すために、マルチウィンドウをを採用しました。
これはモバイルにはない状態管理が求められる、少しチャレンジングな試みでした。
マルチウィンドウをComposeでどう管理するべきか、というドキュメントが当時なかったため、独自に「WindowController」を導入して直感的に管理できるようにしました。

object WindowController {
    val subWindowPageLinks = mutableStateListOf<String>()

    fun openNewPageWindow(link: String) {
        subWindowPageLinks += link
    }

    fun closePageWindow(link: String) {
        subWindowPageLinks.remove(link)
    }
}

@Composable
fun RenderWindows(windowController: WindowController) {
    windowController.subWindowPageLinks.forEach { linkString ->
        Window(onCloseRequest = { windowController.closePageWindow(linkString) }, title = linkString) {
            PageEditViewScreen(linkString, windowController)
        }
    }
}

Applicationの一番rootのところでRenderWindowsを呼べば、WindowControllerが保持しているリンクがWindowに変換されて描画され、ComposableによってそれぞれのWindowの状態が監視される、といった狙いです。
(このアプリでは、初期画面以外の全てのWindowはリンクという文字列から生成されるのでこのような設計になっています。)

もっといい方法があったらご教示願います。

これからどうするのか

思想は立派だけど開発が追いついてない!!
A. はい、、、
頑張ります。コードを書きます。UI整えたり、細かいバグとかを潰したりしたら実行ファイルを配布したいですね。あとは、せっかくKMPで書いているのでモバイル対応もしたいですね。
個人的には、モバイルとデスクトップでデータの同期までできたら、僕も普通のメモに普段使いしてぇなと感じています。早く完成させなきゃ、、!

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?