チャットアプリ

ここではInputManJSのコメントコンポーネントとリッチテキストエディタを組み合わせて、チャットアプリケーションを作成する方法を紹介します。

InputManJSのコメントコンポーネントと、WijmoのTabPanelコントロールを利用して、社内のコミュニケーションを想定したチャットアプリケーションを作成します。このサンプルでは、次のシナリオを確認することができます。 コメントコンポーネント:コメントエディタにリッチテキストエディタを利用し、チャット機能に応じてツールバーの表示項目を設定しています。ヘッダーに並べ替えと検索機能を設定し、ユーザーのメンション、匿名投稿を利用できます。 投稿済みのコメントにフォーカスすると、コンテキストツールバーが表示されます。リアクションやコメントの操作、削除を利用できます。 入力内容が空のままで送信ボタンを押下する場合や入力途中にキャンセルボタンを押下する場合に、警告メッセージが表示されます。 営業チームと雑談チャンネルのコメントエディタはリッチテキストエディタのツールバーを設定しています。 営業チームと雑談チャンネルは、@を入力すると候補のユーザーが表示されます。 雑談チャンネルはリアクションの表示項目と表示される列数を設定しています。 TabPanelコントロール:ノートのページを切り替えることに利用しています。また、TabPanelの表示位置を左側になるようにCSSで変更を加えています。
import '@mescius/wijmo.styles/wijmo.css'; import './styles.css'; import './license'; import * as wjNav from '@mescius/wijmo.nav'; import * as wjCore from '@mescius/wijmo'; import '@mescius/inputman.comment/CSS/gc.inputman.comment.css'; import '@mescius/inputman.richtexteditor/CSS/gc.inputman.richtexteditor.css'; import { InputMan } from '@mescius/inputman.comment'; import * as RichTextEditorControl from '@mescius/inputman.richtexteditor'; import { groupChatComments, commentsWithUser2, commentsWithUser3, freeComments, emojis, users } from './data'; InputMan.appearanceStyle = InputMan.AppearanceStyle.Modern; let theTabPanel = new wjNav.TabPanel('#theTabPanel', { selectedIndexChanged: function (s, e) { const commentContainer = document.querySelector('.wj-tabpanes'); commentContainer.scrollTop = commentContainer.scrollHeight; }, }); let host = theTabPanel.hostElement; let clsName = 'tabs-Left'.toLowerCase(); wjCore.toggleClass(host, clsName, true); theTabPanel.isAnimated = true; const richTextEditorConfig1 = { editorType: InputMan.GcCommentEditorType.GcRichTextEditor, height: 200, baseUrl: '$IMDEMOROOT$/lib/purejs/node_modules/@mescius/inputman.richtexteditor/JS', plugins: [RichTextEditorControl.InputMan.GcRichTextEditorPluginItem.All], menubar: [], toolbar: [ 'emoticons', '|', 'fontsize', 'bold', 'italic', 'underline', 'strikethrough', 'forecolor', 'backcolor', '|', 'blockQuote', 'link', 'restoredraft', ], }; const richTextEditorConfig2 = { editorType: InputMan.GcCommentEditorType.GcRichTextEditor, height: 150, baseUrl: '$IMDEMOROOT$/lib/purejs/node_modules/@mescius/inputman.richtexteditor/JS', plugins: [RichTextEditorControl.InputMan.GcRichTextEditorPluginItem.All], menubar: [], toolbar: [ 'emoticons', '|', 'bold', 'italic', 'strikethrough', 'forecolor', '|', 'link', 'bulList', 'numList', 'blockQuote', ], }; InputMan.GcComment.setResource('ja', InputMan.GcCommentResourceNames.SortBy, ''); const gcComment1 = new InputMan.GcComment(document.getElementById('gcComment1'), { commentMode: InputMan.GcCommentMode.ChatMode, contextToolbar: [ { name: InputMan.GcCommentContextToolbar.AddReactions, collapse: false, }, { name: InputMan.GcCommentContextToolbar.SeparateLine, collapse: false, }, { name: InputMan.GcCommentContextToolbar.Reply, collapse: false, }, { name: InputMan.GcCommentContextToolbar.Edit, collapse: false, }, { name: InputMan.GcCommentContextToolbar.SeparateLine, collapse: false, }, ], userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, editorConfig: richTextEditorConfig1, showIcon: true, avatarType: 'roundedcorner', commentAction: ['addreactions'], commentActionItem: {}, commentInfoAction: ['updatetime',], loadComments: (args) => { return { comments: groupChatComments.sort((a, b) => new Date(a.postTime) - new Date(b.postTime)), hasMore: true, }; }, loadUsersInfoHandler: (context) => { if (context.loadType === InputMan.LoadUserType.FilterText) { return users.filter((u) => u.name.includes(context.value)); } else if (context.loadType === InputMan.LoadUserType.ById) { return users.filter((u) => u.id === context.value); } }, pageSize: 2, header: [ [ { name: InputMan.GcCommentHeaderFooterItem.Sort, align: 'left', }, { name: InputMan.GcCommentHeaderFooterItem.Search, align: 'right', }, ], ], postTimeFormatter: (date) => { const now = new Date(); const postDate = new Date(date); const diffInMs = now - postDate; const diffInSeconds = Math.floor(diffInMs / 1000); const diffInMinutes = Math.floor(diffInSeconds / 60); const diffInHours = Math.floor(diffInMinutes / 60); const diffInDays = Math.floor(diffInHours / 24); if (diffInDays < 1) { if (diffInHours < 1 && diffInMinutes > 0) { return `${diffInMinutes}分前`; } else { return `ただいま`; } } else if (diffInDays <= 7) { return `${diffInDays}日前`; } else { return `投稿日時: ${postDate.toLocaleString()}`; } }, sortInfo: { isDesc: false, sortBy: InputMan.GcCommentSortBy.UpdateTime, }, watermark: { addComment: 'ユーザーをメンションするには「@」を入力します。', searchBox: '検索', continueAddComment: 'コメントを再開します。', }, warningMessage: { emptyContent: 'コメントが入力されていません。', notAllowPostComment: 'コメントを投稿する前にログインしてください。', confirmDeleteComment: 'コメントを削除してもよろしいですか?', }, }); const gcComment2 = new InputMan.GcComment(document.getElementById('gcComment2'), { commentMode: InputMan.GcCommentMode.ChatMode, editorConfig: richTextEditorConfig2, contextToolbar: [ { name: InputMan.GcCommentContextToolbar.AddReactions, collapse: false, }, { name: InputMan.GcCommentContextToolbar.Edit, collapse: false, }, { name: InputMan.GcCommentContextToolbar.SeparateLine, collapse: false, }, ], userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, loadComments: (args) => { return { comments: commentsWithUser2.sort((a, b) => new Date(a.postTime) - new Date(b.postTime)), hasMore: true, }; }, header: [ [ { name: InputMan.GcCommentHeaderFooterItem.Search, align: 'right', }, ], ], }); const gcComment3 = new InputMan.GcComment(document.getElementById('gcComment3'), { commentMode: InputMan.GcCommentMode.ChatMode, editorConfig: richTextEditorConfig2, userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, loadComments: (args) => { return { comments: commentsWithUser3.sort((a, b) => new Date(a.postTime) - new Date(b.postTime)), }; }, header: [ [ { name: InputMan.GcCommentHeaderFooterItem.Search, align: 'right', }, ], ], }); let commentAddComment = document.createElement('div'); commentAddComment.style.color = 'orange'; commentAddComment.append('話題は何でもOK!気軽に参加しましょう!💖'); const gcComment4 = new InputMan.GcComment(document.getElementById('gcComment4'), { commentMode: InputMan.GcCommentMode.ChatMode, editorConfig: richTextEditorConfig1, candidateReactionListColumns: 4, candidateReactionList: emojis, header: [ [ { name: InputMan.GcCommentHeaderFooterItem.Sort, align: 'left', }, { name: InputMan.GcCommentHeaderFooterItem.Search, align: 'right', }, ], ], userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, loadComments: (args) => { return { comments: freeComments.filter((c) => !c.pinned).sort((a, b) => new Date(a.postTime) - new Date(b.postTime)), hasMore: true, }; }, loadUsersInfoHandler: (context) => { if (context.loadType === InputMan.LoadUserType.FilterText) { return users.filter((u) => u.name.includes(context.value)); } else if (context.loadType === InputMan.LoadUserType.ById) { return users.filter((u) => u.id === context.value); } }, watermark: { addComment: commentAddComment, }, });
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <meta name="description" content="実用例 - チャットアプリ" lang="ja" xml:lang="ja" /> <title>実用例 - チャットアプリ</title> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> window.onload = function () { System.import('./src/app'); }; </script> </head> <body> <div class="container-fluid"> <div id="theTabPanel" class="custom-tab"> <div> <a>営業チーム</a> <div> <div id="gcComment1"></div> </div> </div> <div> <a>葛城 孝史</a> <div> <div id="gcComment2"></div> </div> </div> <div> <a>加藤 泰江</a> <div> <div id="gcComment3"></div> </div> </div> <div> <a class="wj-state-active">雑談チャンネル</a> <div> <div id="gcComment4"></div> </div> </div> </div> </div> </body> </html>
body { border: 1px solid #ccc; border-radius: 4px; } .wj-tabheader:hover { background: #fffffc; outline: 2px solid rgba(204, 224, 240, 0.5); } .wj-tabpanel .wj-tabpanes { border: none; width: 75%; } .wj-tabpanel>div>.wj-tabheaders { border: none; width: 20%; } .custom-tab { background: rgb(240, 239, 239); } .wj-tabpanel>div>.wj-tabheaders>.wj-tabheader.wj-state-active { border: 1px solid #ccc; background: #fffffc; color: black; font-weight: normal; } .wj-tabpanel .wj-tabheaders .wj-tabheader:not(.wj-state-active) { font-weight: normal; } .wj-tabpanel.tabs-left .wj-tabheaders .wj-tabheader { text-align: left; } /* tabs on the left */ .wj-tabpanel.tabs-left>div { display: flex; } .wj-tabpanel.tabs-left .wj-tabheaders { display: flex; flex-direction: column; border-right: 1px solid #ddd; } .wj-tabpanel.tabs-left .wj-tabpanes { flex-grow: 1; border-top: none; overflow-x: hidden; height: 600px; } .search-container .search-box:hover { border: 1px solid #6b0ee6 !important; } .search-container .search-box .search-text { color: #6b0ee6 !important; } .search-watermark { overflow: hidden; } .gcim__gccomment { border: 1px solid #ccc; border-radius: 4px; box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1); background-color: #fafdff; } .gcim__gccomment .gcim__gccomment-commentcontainer .comment { padding-bottom: 10px; } .gcim__gccomment[data-comment-mode="chatmode"] .gcim__gccomment-commentcontainer .comment[data-post-by-current-user="true"] { --backcolor: #e1f0fa; } .gcim__gccomment[data-comment-mode="chatmode"] .gcim__gccomment-commentcontainer .comment[data-post-by-current-user="false"] { --backcolor: #faf3e6; } .gcim__gccomment-addcommentwrapper .add_comment_wrapper .add_comment_action .btn_save { font-weight: 700; color: rgb(255, 255, 255) !important; background-color: rgb(44, 62, 80) !important; border: 1px solid rgb(52, 73, 94) !important; border-radius: 8px; padding: 10px 20px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); transition: background-color 0.3s ease, box-shadow 0.3s ease; } .gcim__gccomment-addcommentwrapper .add_comment_wrapper .add_comment_action .btn_save:hover { background-color: rgb(30, 39, 50) !important; box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4); } .gcim__gccomment-addcommentwrapper .add_comment_wrapper .add_comment_action .btn_cancel { background-color: rgb(189, 195, 199) !important; font-weight: 700; color: rgb(52, 73, 94) !important; border: 1px solid rgb(149, 165, 166) !important; border-radius: 8px; padding: 10px 20px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); transition: background-color 0.3s ease, box-shadow 0.3s ease; } .gcim__gccomment-addcommentwrapper .add_comment_wrapper .add_comment_action .btn_cancel:hover { background-color: rgb(171, 183, 183) !important; box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4); } .gcim__gccomment-addcommentwrapper .add_comment_wrapper .add_comment_action .anonymous_checkbox { color: #007b43 !important; }
export const freeComments = [ { id: '1', userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, content: `<b>アナウンス:匿名投稿が可能になる新しいチャンネルを開設しました!🎉🎉🎉</b> <p>このチャンネルでは、ユーザーが自分の名前を公開せずに自由にコメントを投稿できます。フィードバックやアイディア、質問などがあれば、気軽に共有してください。</p> <p>ぜひ、ディスカッションに参加しましょう!</p>`, postTime: new Date(2024, 8, 30, 8, 45, 0), updateTime: new Date(2024, 8, 30, 8, 45, 0), reactions: [ { reactionChar: '👍', count: 2, }, ], }, { id: '2', userInfo: { id: '2', name: '葛城 孝史', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar2.png', }, content: 'おはようございます!元気です。今日も頑張ります!', postTime: new Date(2024, 8, 30, 8, 45, 30), updateTime: new Date(2024, 8, 30, 8, 45, 30), reactions: [ { reactionChar: '💪', count: 3, currentUserReacted: true, }, ], }, { id: '3', userInfo: { id: '3', name: '加藤 泰江', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar3.png', }, content: '今日はちょっと寒いですね。風邪引かないように気を付けましょう!', postTime: new Date(2024, 8, 30, 8, 45, 50), updateTime: new Date(2024, 8, 30, 8, 45, 50), reactions: [ { reactionChar: '😁', count: 1, currentUserReacted: false, }, ], }, { id: '4', userInfo: { id: '2', name: '葛城 孝史', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar2.png', }, content: '寒いですね。', postTime: new Date(2024, 8, 30, 8, 46, 50), updateTime: new Date(2024, 8, 30, 8, 46, 50), parentCommentId: '3', reactions: [ { reactionChar: '😅', count: 2, currentUserReacted: true, }, ], }, { id: '5', userInfo: { id: '6', name: '成宮 真紀', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar6.png', }, content: 'お疲れ様です!皆さん、ランチはどうする予定ですか?', postTime: new Date(2024, 9, 1, 12, 30, 0), updateTime: new Date(2024, 9, 1, 12, 30, 0), reactions: [ { reactionChar: '🍴', count: 3, currentUserReacted: false, }, ], }, { id: '6', userInfo: { id: '5', name: '松沢 誠一', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar5.png', }, content: '今日はラーメンを食べに行こうと思ってます!👍', postTime: new Date(2024, 9, 1, 12, 31, 0), updateTime: new Date(2024, 9, 1, 12, 31, 0), parentCommentId: '5', reactions: [ { reactionChar: '🍜', count: 4, currentUserReacted: true, }, ], }, { id: '7', userInfo: { id: '6', name: '成宮 真紀', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar6.png', }, content: 'ラーメンはいいですね!私はダイエットなので、サラダにしようかな。', postTime: new Date(2024, 9, 1, 12, 32, 0), updateTime: new Date(2024, 9, 1, 12, 32, 0), reactions: [ { reactionChar: '🥗', count: 2, currentUserReacted: true, }, ], }, { id: '8', userInfo: { id: '4', name: '川村 匡', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar4.png', }, content: 'サラダは良いと思いますが、僕はやっぱりがっつりのお肉派です🍖!', postTime: new Date(2024, 9, 1, 12, 33, 20), updateTime: new Date(2024, 9, 1, 12, 33, 20), reactions: [ { reactionChar: '🍖', count: 3, currentUserReacted: false, }, ], }, { id: '9', userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, content: '私は相変わらず牛丼にします。', postTime: new Date(2024, 9, 1, 12, 34, 0), updateTime: new Date(2024, 9, 1, 12, 34, 0), reactions: [ { reactionChar: '🍴', count: 4, currentUserReacted: true, }, ], }, { id: '10', userInfo: { id: '5', name: '松沢 誠一', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar5.png', }, content: '今日はカレーライスでした!美味しかったです!', postTime: new Date(2024, 9, 1, 13, 35, 0), updateTime: new Date(2024, 9, 1, 13, 35, 0), reactions: [ { reactionChar: '👍', count: 2, currentUserReacted: false, }, { reactionChar: '🍛', count: 1, currentUserReacted: true, }, ], }, { id: '11', userInfo: { id: '6', name: '成宮 真紀', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar6.png', }, content: '私はパスタでした。最近ハマっています!', postTime: new Date(2024, 9, 1, 13, 40, 0), updateTime: new Date(2024, 9, 1, 13, 40, 0), reactions: [ { reactionChar: '🍝', count: 2, currentUserReacted: false, }, ], }, { id: '12', userInfo: { id: '3', name: '加藤 泰江', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar3.png', }, content: '今日はいい天気ですね。', postTime: new Date(2024, 9, 2, 15, 0, 0), updateTime: new Date(2024, 9, 2, 15, 0, 0), reactions: [ { reactionChar: '🔥', count: 4, currentUserReacted: true, }, ], }, { id: '13', userInfo: { id: '4', name: '川村 匡', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar4.png', }, content: '明日の夜、予定が空いている方はいらっしゃいますか?一緒に飲みに行きましょう!', postTime: new Date(2024, 9, 3, 16, 45, 0), updateTime: new Date(2024, 9, 3, 16, 45, 0), reactions: [ { reactionChar: '🍺', count: 5, currentUserReacted: true, }, ], }, { id: '14', userInfo: { id: '5', name: '松沢 誠一', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar5.png', }, content: '僕は行きたいです!どこかおすすめの店とかありますか?', postTime: new Date(2024, 9, 3, 16, 50, 0), updateTime: new Date(2024, 9, 3, 16, 50, 0), reactions: [ { reactionChar: '👍', count: 2, currentUserReacted: true, }, ], }, { id: '15', userInfo: { id: '2', name: '葛城 孝史', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar2.png', }, content: `<p>私も行きたいです!ちょっと気になるエスニック料理屋があります。いかがでしょう!</p><p><img src="$IMDEMOROOT$/ja/samples/examples/chatApp/img/ethnic.png" alt="" width="200" height="125" /></p> <p>お店の情報:<a href="https://developer.mescius.jp/inputmanjs" target="_blank" rel="noopener">URL</a></p>`, postTime: new Date(2024, 9, 3, 16, 55, 0), updateTime: new Date(2024, 9, 3, 16, 55, 0), reactions: [ { reactionChar: '👍', count: 2, currentUserReacted: true, }, ], }, { id: '16', userInfo: { id: '4', name: '川村 匡', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar4.png', }, content: 'いいですね。では、明日の定時後はそこで集合しよう。', postTime: new Date(2024, 9, 3, 16, 56, 0), updateTime: new Date(2024, 9, 3, 16, 56, 0), reactions: [ { reactionChar: '😅', count: 1, currentUserReacted: true, }, ], }, { id: '17', userInfo: { id: '6', name: '成宮 真紀', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar6.png', }, content: '最近、ヨガを始めました!', postTime: new Date(2024, 9, 5, 12, 56, 0), updateTime: new Date(2024, 9, 5, 12, 56, 0), reactions: [ { reactionChar: '🧘‍♀️', count: 2, currentUserReacted: false, }, ], }, { id: '18', userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, content: '運動は大事ですね。私も最近朝ランニングを始めました。', postTime: new Date(2024, 9, 5, 12, 56, 20), updateTime: new Date(2024, 9, 5, 12, 56, 20), reactions: [ { reactionChar: '🏃‍♂️', count: 4, currentUserReacted: true, }, ], } ]; export const commentsWithUser2 = [ { id: '1', userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, content: '今月の売上目標ですが、あと1件で達成できそうです。新規顧客の対応は進んでいますか?', postTime: new Date(2024, 9, 1, 9, 0, 0), updateTime: new Date(2024, 9, 1, 9, 0, 0), reactions: [ { reactionChar: '👍', count: 1, }, ], }, { id: '2', userInfo: { id: '2', name: '葛城 孝史', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar2.png', }, content: 'はい、今朝M社と商談を行いました。これから契約に移りますので、適宜にフォローします。', postTime: new Date(2024, 9, 1, 10, 30, 0), updateTime: new Date(2024, 9, 1, 10, 30, 0), reactions: [ { reactionChar: '👍', count: 1, currentUserReacted: true, }, ], }, { id: '3', userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, content: '素晴らしいですね!今後の進捗状況も共有をお願いします。そして、先週の営業報告書はどうでしょうか。確認しましたか?', postTime: new Date(2024, 9, 2, 14, 0, 0), updateTime: new Date(2024, 9, 2, 14, 0, 0), reactions: [ { reactionChar: '👍', count: 1, }, ], }, { id: '4', userInfo: { id: '2', name: '葛城 孝史', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar2.png', }, content: 'はい、確認しました。いくつか顧客の反応が良いので、今後も重点的にフォローします。また、お客様より今月のキャンペーンについて良いフィードバックがありましたので、後ほど報告書に追記しておきます。', postTime: new Date(2024, 9, 3, 11, 15, 0), updateTime: new Date(2024, 9, 3, 11, 15, 0), reactions: [ { reactionChar: '👍', count: 1, currentUserReacted: true, }, ], }, { id: '5', userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, content: '了解です。フィードバックを見て、次の提案を準備しておきましょう。あと、来週の営業会議は水曜日の15時になります。スケジュールを確認してください。', postTime: new Date(2024, 9, 4, 8, 0, 0), updateTime: new Date(2024, 9, 4, 8, 0, 0), reactions: [ { reactionChar: '👍', count: 1, }, ], }, { id: '6', userInfo: { id: '2', name: '葛城 孝史', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar2.png', }, content: '承知しました。顧客の提案内容を整理しておきます。', postTime: new Date(2024, 9, 4, 17, 30, 0), updateTime: new Date(2024, 9, 4, 17, 30, 0), reactions: [ { reactionChar: '👍', count: 1, currentUserReacted: true, }, ], }, ]; export const commentsWithUser3 = [ { id: '1', userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, content: '今月の経費精算書を確認していただけますか?明日までに提出する必要があります。', postTime: new Date(2024, 9, 5, 9, 0, 0), updateTime: new Date(2024, 9, 5, 9, 0, 0), reactions: [ { reactionChar: '👍', count: 1, }, ], }, { id: '2', userInfo: { id: '3', name: '加藤 泰江', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar3.png', }, content: '承知しました。経費精算書を確認して提出します。', postTime: new Date(2024, 9, 5, 9, 30, 0), updateTime: new Date(2024, 9, 5, 9, 30, 0), reactions: [ { reactionChar: '👍', count: 1, currentUserReacted: true, }, ], }, { id: '3', userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, content: '助かります。あと、来週の契約書作成についてもスケジュール調整をお願いします。顧客の確認を待っていますが、準備は進めておきたいです。', postTime: new Date(2024, 9, 5, 10, 0, 0), updateTime: new Date(2024, 9, 5, 10, 0, 0), reactions: [ { reactionChar: '👍', count: 1, }, ], }, { id: '4', userInfo: { id: '3', name: '加藤 泰江', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar3.png', }, content: '承知しました。契約書のひな形を先に準備します。顧客からフィードバックがありましたらすぐ修正できるようにしておきます。', postTime: new Date(2024, 9, 5, 10, 30, 0), updateTime: new Date(2024, 9, 5, 10, 30, 0), reactions: [ { reactionChar: '👍', count: 1, currentUserReacted: true, }, ], }, { id: '5', userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, content: 'ありがとうございます。フィードバックがありましたら、すぐに連絡します。あと、お手数ですが、来月の会議資料の準備もお願いできますか?', postTime: new Date(2024, 9, 5, 11, 0, 0), updateTime: new Date(2024, 9, 5, 11, 0, 0), reactions: [ { reactionChar: '👍', count: 1, }, ], }, { id: '6', userInfo: { id: '3', name: '加藤 泰江', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar3.png', }, content: '承知しました。会議資料のドラフト版を今週中に共有します。また、ご確認をお願いします。', postTime: new Date(2024, 9, 5, 11, 30, 0), updateTime: new Date(2024, 9, 5, 11, 30, 0), reactions: [ { reactionChar: '👍', count: 1, currentUserReacted: true, }, ], }, ]; export const groupChatComments = [ { id: '1', userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, content: 'お疲れ様です。今月の営業目標ですが、あと1件で達成できます。進捗はどうですか?', postTime: new Date(2024, 9, 15, 9, 0, 0), updateTime: new Date(2024, 9, 15, 9, 0, 0), reactions: [ { reactionChar: '👍', count: 3, }, ], }, { id: '2', userInfo: { id: '2', name: '葛城 孝史', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar2.png', }, content: 'お疲れ様です。今週中に1件契約が確定しそうです!それで目標をクリアできる見込みです。', postTime: new Date(2024, 9, 15, 9, 15, 0), updateTime: new Date(2024, 9, 15, 9, 15, 0), reactions: [ { reactionChar: '👍', count: 4, currentUserReacted: true, }, ], }, { id: '3', userInfo: { id: '3', name: '加藤 泰江', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar3.png', }, content: 'この件について、私が契約書を準備しておきますね。顧客から正式な承認が取れましたら、すぐに進められるようにしておきます。', postTime: new Date(2024, 9, 15, 9, 30, 0), updateTime: new Date(2024, 9, 15, 9, 30, 0), reactions: [ { reactionChar: '👍', count: 2, currentUserReacted: true, }, ], }, { id: '4', userInfo: { id: '6', name: '成宮 真紀', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar6.png', }, content: 'お疲れ様です。契約関連の資料について、必要な書類は私からも確認しておきます。', postTime: new Date(2024, 9, 15, 9, 45, 0), updateTime: new Date(2024, 9, 15, 9, 45, 0), reactions: [ { reactionChar: '👍', count: 2, currentUserReacted: true, }, ], }, { id: '5', userInfo: { id: '5', name: '松沢 誠一', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar5.png', }, content: '僕のほうでも、契約書の内容を確認しておきますね。万が一不備がある場合、すぐ連絡します。', postTime: new Date(2024, 9, 15, 10, 0, 0), updateTime: new Date(2024, 9, 15, 10, 0, 0), reactions: [ { reactionChar: '👍', count: 3, currentUserReacted: true, }, ], }, { id: '6', userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, content: '皆さん、ありがとうございます。そうしましたら、色々な準備をよろしくお願いいたします。', postTime: new Date(2024, 9, 15, 10, 15, 0), updateTime: new Date(2024, 9, 15, 10, 15, 0), reactions: [ { reactionChar: '👍', count: 2, }, ], }, { id: '7', userInfo: { id: '3', name: '加藤 泰江', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar3.png', }, content: 'ちなみに、明日は経費精算の締め切りとなります。皆さん、書類の提出をお願いします。', postTime: new Date(2024, 9, 15, 10, 30, 0), updateTime: new Date(2024, 9, 15, 10, 30, 0), reactions: [ { reactionChar: '👍', count: 3, currentUserReacted: true, }, ], }, { id: '8', userInfo: { id: '2', name: '葛城 孝史', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar2.png', }, content: '承知しました。何件か申請したいと思います。後ほど提出します。', postTime: new Date(2024, 9, 15, 10, 45, 0), updateTime: new Date(2024, 9, 15, 10, 45, 0), reactions: [ { reactionChar: '👍', count: 2, currentUserReacted: false, }, ], }, { id: '9', userInfo: { id: '6', name: '成宮 真紀', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar6.png', }, content: '特に交通費関連の書類が少し遅れているので、それが届き次第まとめます。', postTime: new Date(2024, 9, 15, 11, 0, 0), updateTime: new Date(2024, 9, 15, 11, 0, 0), reactions: [ { reactionChar: '👍', count: 1, currentUserReacted: true, }, ], }, { id: '10', userInfo: { id: '5', name: '松沢 誠一', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar5.png', }, content: '交通費の件、少し確認が必要ですね。担当者に問い合わせて、すぐに進められるようにします。', postTime: new Date(2024, 9, 15, 11, 15, 0), updateTime: new Date(2024, 9, 15, 11, 15, 0), reactions: [ { reactionChar: '👍', count: 2, currentUserReacted: true, }, ], }, { id: '11', userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, content: '交通費精算の件、よろしくお願いします。特に急ぎの案件なので、完了したらすぐ共有してください。', postTime: new Date(2024, 9, 15, 11, 30, 0), updateTime: new Date(2024, 9, 15, 11, 30, 0), reactions: [ { reactionChar: '👍', count: 2, }, ], }, { id: '12', userInfo: { id: '6', name: '成宮 真紀', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar6.png', }, content: '了解しました。精算が完了次第、全員に共有します。', postTime: new Date(2024, 9, 15, 11, 45, 0), updateTime: new Date(2024, 9, 15, 11, 45, 0), reactions: [ { reactionChar: '👍', count: 1, currentUserReacted: true, }, ], }, { id: '13', userInfo: { id: '5', name: '松沢 誠一', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar5.png', }, content: '経費精算書に一部不明点がありましたので、詳細を確認後、追加書類を提出します。', postTime: new Date(2024, 9, 15, 12, 0, 0), updateTime: new Date(2024, 9, 15, 12, 0, 0), reactions: [ { reactionChar: '👍', count: 3, currentUserReacted: true, }, ], }, { id: '14', userInfo: { id: '3', name: '加藤 泰江', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar3.png', }, content: '松沢さん、追加書類の提出が確認できたらお知らせください。その後、精算に入れます。', postTime: new Date(2024, 9, 15, 12, 15, 0), updateTime: new Date(2024, 9, 15, 12, 15, 0), reactions: [ { reactionChar: '👍', count: 2, currentUserReacted: true, }, ], }, { id: '15', userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, content: '経費精算に関しては、このまま進めて問題ないかと思いますが、何か課題があれば教えてください。', postTime: new Date(2024, 9, 15, 12, 30, 0), updateTime: new Date(2024, 9, 15, 12, 30, 0), reactions: [ { reactionChar: '👍', count: 3, }, ], }, { id: '16', userInfo: { id: '3', name: '加藤 泰江', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar3.png', }, content: '現時点では大きな問題はありませんが、経費関連の締め切りを確認したほうが良いかもしれません。', postTime: new Date(2024, 9, 15, 12, 45, 0), updateTime: new Date(2024, 9, 15, 12, 45, 0), reactions: [ { reactionChar: '👍', count: 1, currentUserReacted: true, }, ], }, { id: '17', userInfo: { id: '6', name: '成宮 真紀', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar6.png', }, content: '締め切りは今月末までですが、余裕を持って提出したほうがいいですね。早めに動きます。', postTime: new Date(2024, 9, 15, 13, 0, 0), updateTime: new Date(2024, 9, 15, 13, 0, 0), reactions: [ { reactionChar: '👏', count: 2, currentUserReacted: true, }, ], }, { id: '18', userInfo: { id: '5', name: '松沢 誠一', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar5.png', }, content: 'ありがとうございます。私も早めに準備を整えますね。進捗があればすぐ共有します。', postTime: new Date(2024, 9, 15, 13, 15, 0), updateTime: new Date(2024, 9, 15, 13, 15, 0), reactions: [ { reactionChar: '👏', count: 1, currentUserReacted: true, }, ], }, { id: '19', userInfo: { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, content: '来週の営業会議までに経費の精算を完了させるように進めましょう。皆さん、よろしくお願いします。', postTime: new Date(2024, 9, 15, 13, 30, 0), updateTime: new Date(2024, 9, 15, 13, 30, 0), reactions: [ { reactionChar: '👏', count: 3, }, ], }, { id: '20', userInfo: { id: '2', name: '葛城 孝史', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar2.png', }, content: '承知しました。進捗を共有しながら、順調に進められるようサポートします。皆さんもよろしくお願いします。', postTime: new Date(2024, 9, 15, 13, 45, 0), updateTime: new Date(2024, 9, 15, 13, 45, 0), reactions: [ { reactionChar: '🔥', count: 2, currentUserReacted: true, }, ], }, ]; export const users = [ { id: '1', name: '森上 偉久馬', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar1.png', }, { id: '2', name: '葛城 孝史', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar2.png', }, { id: '3', name: '加藤 泰江', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar3.png', }, { id: '4', name: '川村 匡', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar4.png', }, { id: '5', name: '松沢 誠一', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar5.png', }, { id: '6', name: '成宮 真紀', avatar: '$IMDEMOROOT$/ja/samples/examples/chatApp/img/avatar6.png', }, ]; export const emojis = [ '👍', '👏', '🔥', '😯', '🤔', '😀', '😁', '😂', '🤣', '😃', '😄', '😅', '😆', '😉', '😊', '😋', '🤩', '🏃‍♂️', '🧘‍♀️', '🍺', '🍝', '🍛', '🍴', '🍖', '🥗', '🍜', '💪', ];
System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true, }, meta: { '*.css': { loader: 'css' }, }, paths: { // paths serve as alias 'npm:': 'node_modules/', }, // map tells the System loader where to look for things map: { '@mescius/inputman': 'npm:@mescius/inputman/index.js', '@mescius/inputman/CSS': 'npm:@mescius/inputman/CSS', '@mescius/inputman.richtexteditor': 'npm:@mescius/inputman.richtexteditor/index.js', '@mescius/inputman.richtexteditor/CSS': 'npm:@mescius/inputman.richtexteditor/CSS', '@mescius/inputman.comment': 'npm:@mescius/inputman.comment/index.js', '@mescius/inputman.comment/CSS': 'npm:@mescius/inputman.comment/CSS', '@mescius/wijmo': 'npm:@mescius/wijmo/index.js', '@mescius/wijmo.styles': 'npm:@mescius/wijmo.styles', '@mescius/wijmo.cultures': 'npm:@mescius/wijmo.cultures', '@mescius/wijmo.nav': 'npm:@mescius/wijmo.nav/index.js', css: 'npm:systemjs-plugin-css/css.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build': 'npm:systemjs-plugin-babel/systemjs-babel-browser.js', }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'js', }, node_modules: { defaultExtension: 'js', }, }, });