YAPC2016Gyazzスライド
ページ右側のStart presentationでスライドになる
ReactでGyazzというWikiを自作して運用している話
@shokai shokai.icon
Nota, Inc.
スクリーンショット共有サービス
アニメGIFでも撮影できる
プルリクにも便利
私に質問や感想を言うとあげます
トーク後でも可
15枚ぐらいある
https://gyazo.com/02fb6e1009a6115079f2bb6603971b73
Gyazzという名のWiKi
2人で作っている rakusai.icon shokai.icon
トーク概要より
WYSIWYGで画像やリンクも貼れるけど、編集ツールバーやボタンが無いエディタ markdownより簡単なシンタックスで編集できる
Gitを参考にsubversionみたいなものを実装した
社内で運用してて、3ヶ月で900ページくらい作られている
このスライドもGyazzから生成している
「五行の送り火」を「大文字焼き」って書いたら勝手に修正されてた
ワイキキ空港のターミナル連絡バスのこと
https://gyazo.com/b245c3244dc646ddc29a8a9cafd15d3b
みんなで書けるwebサイト
WiKiのつらみ
メジャーなWikiの方式
独特のシンタックスを手で書く方式
覚えるのつらい
さっき見ていた場所をちょっと直したいだけなのに、編集モードに入ると全体が生テキストになってる・・
WYSIWYGエディタ方式
見たまま編集できる
ツールバー、メニューがたくさん
一度作った綺麗な見た目の段落と、同じスタイルの段落をもう一個作るのが難しい
文章書いてる時間より装飾整えてる時間の方が長い・・ (shokai.icon個人の見解です)
Gyazzとは?
増井俊之.icon が10年ぐらい前に作った
https://gyazo.com/0e7cd8cde4a705f8d5fa46b94053486a
ここ数年、いろんな人がGyazzクローンを作っている rakusai.iconshokai.icon
編集・閲覧のモード切り替えが無い
カーソルのある行だけがWiKi Syntaxむき出しになる
かんたんなSyntax
がんばって書いたり覚えたりしなくても、適当に見やすく表示する
ページ間リンクを貼っておけば関連検索で発見できる
階層は無い、Web的
アイディアを書いておくと、忘れた頃に関連リンクに現れてピンときたりする
複数人で同時編集できる
ほぼ 角カッコで囲うだけ
外部リンク
[URL]
内部リンク
[ページタイトル]
#ページタイトル ハッシュタグ風
タイトル付き外部リンク
[URL タイトル]
[タイトル URL] 逆順でもいい
画像埋め込み
[画像のURL]
リンク付き画像
[画像のURL リンク先URL]
[リンク先URL 画像のURL] 逆順でもいい
アイコン記法
[ページタイトル.icon]
shokai.icon
アイコンタワー記法
[ページタイトル.icon*数字]
shokai.icon*20
太字
[[あいうえお]] 角カッコ2つ
あいうえお
インラインコード
console.log("hello") バッククオートで囲う
コードブロック記法
code:test.js
function () {
alert('hello')
}
code:言語名もしくはcode:ファイル名の下のブロックに色がつく
CLI記法
$ npm install jquery -save
% git init
行頭がコマンドっぽい行に色がつく
(デモ)
(デモ:ページを作ってみる)
hashタグ
関連ページ
外部リンク
画像うめこみ、リンクつける
CLI記法
codeblock記法
アイコン記法
asadf
アイコン記法で投票
https://gyazo.com/8afa1ca644575b370cc5518980590b21
カーソル行がsyntaxむき出しになるの重要
「これどう書いてるのかな?」がすぐ見れる
HTMLのソース見て勉強したのを思い出す
実装の話
実装環境
エディタの実装
カーソルの縦棒はdiv
緑の範囲選択もdiv3つ
隠し<textarea />
IMEウィンドウを見せるためだけに存在する
カーソルの右側に浮いていて、ついてくる
https://gyazo.com/688d80344a2b353762ec9c79e68a637b
Atom.iconが参考になった
y行目のx文字目の画面上の座標はどこか?
生テキストこんにちはを
1文字ずつ分割して
code:editor.html
<div class='lines'>
<div class='line' id='L1'>
<span class='c-1'>こ</span>
<span class='c-2'>ん</span>
<span class='c-3'>に</span>
<span class='c-4'>ち</span>
<span class='c-5'>は</span>
</div>
</div>
jQueryで位置を取得する
let {left, top} = $('.lines #L1 .c-4').position()
クリックした位置から何行目の何文字目なのか?を求める
逆をやればいい
あとはカーソル移動やemacsキーバインド等を自前で実装すればok
ReactとjQueryは相性悪い?
よくインターネットに書いてある
jQueryでDOM書き換えしなければok
jQuery クロスブラウザで座標の扱いが完璧っぽい
ReactとjQueryでflux
https://facebook.github.io/flux/docs/overview.html https://gyazo.com/01b6bcb163603d4d4a58a0ac714919a3.png
viewはstore (stateとprops)からのみ作られる
viewが他のviewを書き換えない
他のviewの位置を使って描画するviewはどうするの?
他のview componentの位置で位置補正するcomponent
storeが変更される
render()
componentDidUpdateが発火
ここでjQueryでDOMを見て座標取得
storeを更新、もしくは自分のstateを更新する
this.setState({x: 36, y: 250}) // 座標をセット
再renderされる
Fluxの円環の理を2回回すイメージ
https://facebook.github.io/flux/docs/overview.html https://gyazo.com/01b6bcb163603d4d4a58a0ac714919a3.png
複数人で同時編集
同時編集
https://gyazo.com/20b4fe90c13dafd705d1f75d02adb4de
こういう「コミット」をやりとりすればなんとかなるのでは!?
code:commit.json
{
"id": hash,
"parent_id": parent_hash, // 1つ前への参照
}
編集の命令は3つだけ
insert
隣の行のidを指定して新しい行を追加
code:js
{
_insert: positionId, // 文字を挿入する一つ下の位置にある行のId
lines: {
text: text,
id: lineId // 新しく生成された行のid
}
}
新規に行を挿入する
最後に挿入するときは、特殊IDの_endを指定する。
複数行を挿入するときは、insertを複数個作る
update
idを指定して更新
code:js
{
_update: lineId, // 変更する行のId
lines: { text: text }
}
行を変更する
delete
idを指定して削除
code:js
{
_delete: lineId, // 削除する行のId
lines: -1
}
行を削除する
コンフリクトしたら?
ユーザー側でmerge画面にするわけにはいかない
コンフリクト判定はサーバー側
clientはとりあえずpushする
pushがrejectされたらpull
git rebaseのような操作をする
気合マージ
mergeしよう→コンフリクト→pullしてみる
→insertが参照していた行が削除されてる、どこにinsertしていいのかわからない!
→commitをさかのぼって、「削除された行を参照したinsertをした行」を参照してinsertする
commitの中のinsert/update系をmergeして並べ替える
https://gyazo.com/c96ef3b3dbb41784bf29e3dc7e9df130
自分がやった操作のみをundoしたい
同時編集中の他人の操作はundoしたくない
revertコミットを作って貯めておく
pushしてコンフリクトしなかったcommit
insert
同じ行idをdelete
update
元のテキストにupdate
delete
元の位置にinsert
ctrl-Zで逆順に適用する
おわり・まとめ
WYSIWYGで画像やリンクも貼れるけど、編集ツールバーやボタンが無いエディタ
Socket.IOと自作の同期システムでうまいこと同時編集できる
https://gyazo.com/0e7cd8cde4a705f8d5fa46b94053486a
We are hiring
https://gyazo.com/66e38989c110a0c6386e2f0c20dd6b75
五山の送り火で有名な大文字山が見える
フルリモート可
https://gyazo.com/715507b411a50c80e5a6ac9f9fc2cd35.png
YAPC2016Gyazzスライド