PageSourceSearch

https://cojicaji.jp/assets/app/components/article/comment/list_item-35e4c668.js

js cojicaji.jp collected 2026-10-04 00:10:12 UTC 5,585 bytes, 159 lines download raw bytes

1/**
2 * 名前空間の初期化
3 * Rails 8 / Importmap (ESM) 移行に伴い、windowオブジェクト経由で定義を統合します。
4 */
5var App = App || window.App || function App() {};
6App.Components = App.Components || function Components() {};
7App.Components.Article = App.Components.Article || function Article() {};
8App.Components.Article.Comment = App.Components.Article.Comment || function Comment() {};
9
10App.Components.Article.Comment.ListItem = function (comment, isLiked = false) {
11  // コメント本体
12  this.comment = comment;
13  this.isLiked = isLiked;
14};
15
16(function () {
17  App.Components.Article.Comment.ListItem.likedYetClassName = "yet";
18  App.Components.Article.Comment.ListItem.clickedClassName = "clicked";
19
20  /** コメントリストのエレメントを生成して返す */
21  App.Components.Article.Comment.ListItem.prototype.getElement = function() {
22    const self = this;
23
24    // 要素作成
25    const commentListItemElement = self._createElement();
26
27    // イベント追加
28    const commentLikeElement = self._getCommentLikeElement(commentListItemElement);
29    if(commentLikeElement) {
30      commentLikeElement.addEventListener('click', async function() {
31        await self._handleLikeClickEvent();
32      });
33    }
34
35    return commentListItemElement;
36  }
37
38  /**
39   * コメントDOMの生成
40   *
41   * @param commentModel
42   * @returns {HTMLElement}
43   * @private
44   */
45  App.Components.Article.Comment.ListItem.prototype._createElement = function () {
46    const self = this;
47
48    const commentLikeConditionClass = (self.isLiked) ? "" : "yet";
49
50    let commentElement = document.createElement("article");
51    commentElement.classList.add("comment");
52
53    const source = `
54    <div class="comment__body">
55      <a class="comment-contents" href="${self.comment.pagePath()}">
56        <p class="comment-contents__text">${self.comment.comment}</p>
57        <!-- 画像があれば追加する -->
58      </a>
59    </div>  
60    <div class="comment__authors">
61      <div class="comment-author">
62        <a href="${self.comment.user.path()}">
63          <img src="${self.comment.user.iconUrl}" alt="${self.comment.user.name}">
64          <span>${self.comment.user.name}</span>
65        </a>
66      </div>
67    </div>
68
69    <div class="comment__actions">
70      <div class="comment-actions">
71        <p class="comment-actions__like ${commentLikeConditionClass}" data-app-comment-id="${self.comment.id}">
72          ${self.comment.likeCount}
73        </p>
74        <!-- @todo: 返信実装したら表示する
75        <p class="comment-actions__reply">返信する</p>
76        -->
77      </div>
78    </div>
79  `
80
81    commentElement.innerHTML = source;
82
83    // 写真がある場合は追加
84    if(self.comment.photoUrl !== "") {
85      const photoInsertTargetElement = commentElement.getElementsByClassName('comment-contents__text')[0];
86
87      photoInsertTargetElement.insertAdjacentHTML('afterend', `
88      <div class="comment-contents__photo">
89        <img src="${self.comment.photoUrl}" alt="カジレポ写真" >
90      </div>`);
91    }
92
93    return commentElement;
94  }
95
96  App.Components.Article.Comment.ListItem.prototype._handleLikeClickEvent = async function () {
97    const self = this;
98
99    try {
100      // @memo: APIリクエストが成功すれば、処理が正常完了したとみなす
101      const repository = new App.Repository.AuthenticatedUserRepository();
102
103      // @memo: コード的には同期する必要があるけどUXが悪い(反応が遅い)ので、localStorageに保存するなど工夫が必要
104      const hoge = (self.isLiked) ? await repository.deleteCommentLike(self.comment.id)
105        : await repository.postCommentLike(self.comment.id);
106
107      const mode = self.isLiked? 'delete' : 'post';
108      App.Common.Notification.sendCommentLikeEvent(mode);
109
110      // 後処理
111      self.isLiked = !self.isLiked;
112      self._changeUi();
113    } catch (error) {
114      // APIエラーが起きたときは、要素をかえない
115      console.error(error);
116    }
117  };
118
119  /** コメント部分のエレメントを取得する */
120  App.Components.Article.Comment.ListItem.prototype._getCommentLikeElement = function(element = document) {
121    const self = this;
122    return element.querySelector(`[data-app-comment-id="${self.comment.id}"]`);
123  }
124
125  App.Components.Article.Comment.ListItem.prototype._changeUi = function () {
126    console.log('change-ui');
127
128    const self = this;
129    const likedYetClassName = App.Components.Article.Comment.ListItem.likedYetClassName;
130    const clickedClassName = App.Components.Article.Comment.ListItem.clickedClassName;
131
132    const commentLikeElement = self._getCommentLikeElement();
133    const currentCommentLikeCount = parseInt(commentLikeElement.innerText);
134
135    if(commentLikeElement) {
136      const hasAlreadyLikedYet = Array.from(commentLikeElement.classList).includes(likedYetClassName);
137      if (hasAlreadyLikedYet) {
138        // 未いいね -> いいね済み
139        commentLikeElement.innerText = (currentCommentLikeCount + 1);
140
141        commentLikeElement.classList.add(clickedClassName);
142        commentLikeElement.classList.remove(likedYetClassName)
143      } else {
144        // いいね済み -> 未いいね
145        commentLikeElement.innerText = (currentCommentLikeCount - 1);
146
147        commentLikeElement.classList.remove(clickedClassName);
148        commentLikeElement.classList.add(likedYetClassName)
149      }
150    }
151  }
152
153}());
154
155/**
156 * グローバル空間への公開
157 * application.js等から参照可能にするため、windowオブジェクトに登録します。
158 */
159window.App = App;

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.