Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Eight メンション機能の
フロントエンド実装 / Eight Mention Frontend

mokuo
October 22, 2018

Eight メンション機能の
フロントエンド実装 / Eight Mention Frontend

「プラットフォームサービスの成長を支える技術〜Web現場Meetup #4」で発表した際の資料になります。
https://pixta-inc.connpass.com/event/103943/

mokuo

October 22, 2018
Tweet

More Decks by mokuo

Other Decks in Programming

Transcript

  1. Eight メンション機能の
    フロントエンド実装
    DSOC Development Group
    ΤϯδχΞ
    ໦ా༔Ұ࿠
    プラットフォームサービスの成⻑を⽀える技術〜
    Web現場Meetup
    #4
    2018/10/22

    View Slide

  2. ⾃⼰紹介

    View Slide

  3. プロフィール
    • 名前 : ⽊⽥ 悠⼀郎
    • 趣味 : テニス、個⼈開発、ブログ
    • Twitter : @mokuo_
    • GitHub : mokuo
    • Qiita : @mokuo
    • 個⼈ブログ : blog.mokuo.me

    View Slide

  4. 経歴
    • SIer, Rails 受託開発会社などを経験
    • 2018年2⽉ Sansan ⼊社 Eight 事業部配属
    • Rails エンジニアとして⼊社したが、気づくと React を書いていた
    • メンション機能のWebフロントエンド実装を担当
    • 2018年6⽉ DSOC に異動
    • Rails エンジニアに戻る
    • GEES(名刺データ化システム)の開発・運⽤をやっています

    View Slide

  5. DSOC について
    5
    • Data Strategy & Operation Center
    • 「データ⽣成から活⽤へ」
    • 名刺のデータ化
    • 新たな価値
    参照 : https://jp.corp-sansan.com/dsoc/about.html

    View Slide

  6. アジェンダ

    View Slide

  7. アジェンダ
    - Eight 開発環境
    - Eight メンション機能とは
    - Eight メンション機能の設計
    - Eight メンション機能のサーバーサイド
    - Eight メンション機能のフロントエンド
    - 使⽤ライブラリ
    - Eight における実装

    View Slide

  8. Eight 開発環境
    8

    View Slide

  9. Eight 開発環境
    - サーバーサイド
    - Ruby on Rails
    - フロントエンド
    - React + Redux
    - インフラ
    - AWS

    View Slide

  10. Eight メンション機能とは
    10

    View Slide

  11. Eight メンション機能とは
    - 投稿をするとき、特定の相⼿をメンションする – Eight ヘルプ
    11
    ౤ߘྫ ίϝϯτྫ

    View Slide

  12. メンション機能の設計
    12

    View Slide

  13. メンション機能の設計
    - 設計にあたり、他サービスを調査
    13

    View Slide

  14. Twitter
    - Twitter API ドキュメント
    - メンション位置情報を保持
    14
    [
    {
    "text": "@jasoncosta @themattharris Hey! Going to be in Frisco in
    October. Was hoping to have a meeting to talk about @thinkwall if you're
    around?",
    "mentions": [
    {
    "user_name": "Jason Costa",
    ”user_id": 14927800,
    "indices": [0, 11],
    "screen_name": "jasoncosta”
    },
    {
    "user_name": "Matt Harris",
    "user_id": 777925,
    "indices": [12, 26],
    "screen_name": "themattharris”
    },
    {
    "user_name": "ThinkWall",
    "user_id": 117426578,
    "indices": [109, 119],
    "screen_name": "thinkwall”
    }
    ]
    }
    ]
    @jasoncosta @themattharris Hey! Going to be in
    Frisco in October. Was hoping to have a meeting to
    talk about @thinkwall if you're around?",
    දࣔ͢Δࡍʹ૷০

    View Slide

  15. Twitter ⽅式のメリット・デメリット
    - メリット
    - テキストを置換する必要がない
    - デメリット
    - 投稿を更新する際にメンション位置も更新する必要がある
    15

    View Slide

  16. Slack
    - Slack API ドキュメント
    - メンション部分をプレースホルダーとして
    保持
    16
    [
    {
    "text": " Hey , did you see my file? ",
    "mentions": [
    {
    ”user_name": "Jason Costa",
    ”user_id": 024BE7LH,
    "screen_name": "jasoncosta”
    },
    ]
    }
    ]
    Hey @jasoncosta, did you see my file?
    දࣔ͢Δࡍʹஔ׵

    View Slide

  17. Slack ⽅式のメリット・デメリット
    - メリット
    - メンション位置を更新する必要がない
    - デメリット
    - メンション部分を テキスト <=> プレースホルダ で変換・逆変換する必要があ

    17
    @jasoncosta ó

    View Slide

  18. Eight はどうしたか
    - 投稿を編集できる場合、メンション位置を更新し続けるのは⼤変
    - Twitter は投稿を編集できないので、メンション位置を更新する必要がない
    - プレースホルダーが適していると判断
    18

    View Slide

  19. Eight メンション機能のサーバーサイド
    19

    View Slide

  20. テーブル定義(イメージ)
    20
    users
    - id
    - name
    - …
    posts
    - id
    - content
    - …
    mentions
    - id
    - user_id
    - post_id

    View Slide

  21. Eight メンション機能のフロントエンド
    21

    View Slide

  22. 使⽤ライブラリ
    22

    View Slide

  23. メンション機能に使⽤したライブラリ
    - Draft.js
    - DraftJS Plugins
    23

    View Slide

  24. Draft.js とは
    - React 向けリッチテキストエディタ
    - 引⽤、箇条書き、コードブロック、太字・・・etc
    - Facebook 製
    - https://draftjs.org/
    24

    View Slide

  25. DraftJS Plugins とは
    - Draft.js のプラグイン
    - 絵⽂字、メンション、ハッシュタグ・・・etc
    - https://www.draft-js-plugins.com/
    25

    View Slide

  26. Draft.js の概念
    - 主な登場⼈物は5⼈
    - EditorState
    - ContentState
    - ContentBlock
    - CharacterMetadata
    - Entity
    - 実態は Immutable.js の Record
    26

    View Slide

  27. Entity について
    - 引⽤、太字、メンションなどをを Entity という概念で扱う。
    - CharacterMetadata (1⽂字)ごとに entity を持っていて、1以上の数値か null
    が⼊る。
    - 例)⼭⽥太郎 さん
    - `entity: 1` => メンション
    27
    editorState.getCurrentContent().getBlockMap().first()
    .getCharacterList().toJS()
    =>
    [
    {style: [], entity: "1"}, #⼭
    {style: [], entity: "1"}, #⽥
    {style: [], entity: "1"}, #太
    {style: [], entity: "1"}, #郎
    {style: [], entity: null}, #さ
    {style: [], entity: null}, #ん
    ]

    View Slide

  28. Draft.js と仲良くなるために
    - Create React App に Draft.js を⼊れて動作検証
    28

    View Slide

  29. Eight における実装
    29

    View Slide

  30. 実装例 : フィードにメンションを表⽰する
    1. サーバーから投稿⽂とメンション情報を取得
    2. 投稿⽂をプレーンテキスト、メンション、URLに分類
    - オブジェクトの配列を⽣成
    3. 表⽰
    - 2. で作った配列をコンポーネントに渡す
    30

    View Slide

  31. オブジェクトの配列を⽣成するイメージ
    31
    # 実際には、text と mentions はサーバーから送られてきます
    const text = ‘ さん、URLはhttps://example.comです。';
    const mentions = fromJS([
    {
    mentionId: 1,
    user: {
    id: 123456,
    name: '⼭⽥ 太郎',
    },
    }
    ]);
    const objects = convertToObjects(text, mentions);
    =>
    [
    { type: 'mention', props: { href: '/users/123456' }, body: '⼭⽥ 太郎' },
    { type: 'plainText', body: ' さん、URLは' },
    { type: 'url' , props: { href: 'https://example.com' }, body: 'https://example.com' },
    { type: 'plainText', body: 'です。' }
    ];

    View Slide

  32. 表⽰部分のイメージ
    ⼭⽥太郎 さん、URLは https://example.com です。
    32

    =>
    ⼭⽥ 太郎
    さん、URLは
    https://example.com
    です。

    View Slide

  33. 他にも、以下のような機能を実装
    - 新規投稿でメンションできる
    - 投稿編集でメンションを追加・削除できる
    - コメントでも投稿と同様にメンションできる
    - コメント返信でメンションされる
    - ⾏動ログの取得
    - アプリ通知
    33

    View Slide

  34. 反省点
    - Slack ⽅式ではなく Twitter ⽅式の⽅がシンプルに実装できたかもしれない
    - Twitter ⽅式 : メンション位置情報を保持
    - Slack ⽅式 : プレースホルダーに置換
    - 正規表現で毎回置換するのが⼤変
    - Draft.js が位置情報を持ってくれていた
    34

    View Slide

  35. ご清聴ありがとうございました。
    35

    View Slide