PageSourceSearch

https://cojicaji.jp/assets/app/components/like_button-6950092b.js

js cojicaji.jp collected 2026-10-04 00:10:19 UTC 4,875 bytes, 158 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() {};
7
8App.Components.LikeButton = function (article) {
9  this.article = article;
10
11  this.isLiked = false;
12
13  this.repository = new App.Repository.AuthenticatedUserRepository();
14};
15
16(function () {
17  App.Components.LikeButton.wrapTargetId = 'js-app-like-wrap';
18  App.Components.LikeButton.buttonId = 'js-app-like';
19  App.Components.LikeButton.buttonConfig = {
20    put: {
21      text: 'いいねする',
22      src: "/images/app/articles/buttons/[email protected]"
23    },
24    delete: {
25      text: 'いいねを取り消す',
26      src: "/images/app/articles/buttons/[email protected]"
27    },
28  };
29
30  App.Components.LikeButton.prototype.show = async function () {
31    const self = this;
32
33    // article情報がないとイイね追加、削除できないので以降の処理を行う必要がない
34    if(!self.article) return;
35
36    if(self._isInserted()) return;
37
38    self.isLiked = await self._isLiked();
39    self._insertButton();
40    self._registEvent();
41  };
42
43  App.Components.LikeButton.prototype._isInserted = function () {
44    const self = this;
45
46    const wrapper = document.getElementById(App.Components.LikeButton.wrapTargetId);
47    if (!wrapper) {
48      return false;
49    }
50
51    return (wrapper.innerHTML != '');
52  };
53
54  App.Components.LikeButton.prototype._isLiked = async function () {
55    const self = this;
56    let isLiked = false;
57
58    // 認証していないユーザはAPI問い合わせ不要
59    if (!CojicajiAppUser.instance.isAuthenticated) {
60      return isLiked;
61    }
62
63    // 認証済みのときだけAPIを呼び出しlikeステータスを取得する
64    isLiked = await self.repository.isLiked(self.article.id);
65
66    return isLiked
67  }
68
69  App.Components.LikeButton.prototype._insertButton = function () {
70    const self = this;
71
72    const buttonElement = self._getLikeButton();
73    const likeButtonWrapper = document.getElementById(App.Components.LikeButton.wrapTargetId);
74    likeButtonWrapper.insertAdjacentElement('afterbegin', buttonElement);
75  }
76
77  App.Components.LikeButton.prototype._getLikeButton = function () {
78    const self = this;
79
80    const likeButtonId = App.Components.LikeButton.buttonId;
81    let likeButton = document.getElementById(likeButtonId);
82    if (!likeButton) {
83      likeButton = self._createButton();
84    }
85
86    return likeButton;
87  }
88
89  App.Components.LikeButton.prototype._createButton = function () {
90    const self = this;
91
92    const likeButtonId = App.Components.LikeButton.buttonId;
93    const likeButton = document.createElement('div');
94    likeButton.classList.add('article-like-button');
95    likeButton.id = likeButtonId;
96
97    // 空のimgタグを挿入する。srcやaltは別途ステータスに応じて書き換える
98    const buttonImageElement = document.createElement('img');
99    likeButton.insertAdjacentElement('afterbegin', buttonImageElement);
100
101    self._changeButtonSrc(likeButton);
102
103    return likeButton;
104  }
105
106  App.Components.LikeButton.prototype._changeButtonSrc = function (button) {
107    const self = this;
108
109    const config = self._getButtonConfig();
110
111    button.getElementsByTagName("img")[0].src = config.src;
112    button.getElementsByTagName("img")[0].alt = config.alt;
113  }
114
115  App.Components.LikeButton.prototype._getButtonConfig = function () {
116    const self = this;
117
118    return (self.isLiked) ?
119      App.Components.LikeButton.buttonConfig.delete
120      : App.Components.LikeButton.buttonConfig.put
121  }
122
123  App.Components.LikeButton.prototype._registEvent = function () {
124    const self = this
125
126    const likeButton = self._getLikeButton();
127    if (likeButton) {
128      likeButton.addEventListener('click', async function () {
129        await self._handleLikeClickEvent();
130      });
131    }
132  }
133
134  App.Components.LikeButton.prototype._handleLikeClickEvent = async function () {
135    const self = this;
136    const mode = self.isLiked ? 'delete' : 'post';
137
138    try {
139      // @memo: APIリクエストが成功すれば、処理が正常完了したとみなã
139™
140      const newLikedStatus = (self.isLiked) ? await self.repository.deleteLike(self.article.id)
141        : await self.repository.postLike(self.article.id);
142      App.Common.Notification.sendLikeEvent(mode);
143
144      self.isLiked = !self.isLiked;
145      const likeButton = self._getLikeButton();
146      self._changeButtonSrc(likeButton);
147    } catch (error) {
148      // APIエラーが起きたときは、要素をかえない
149      console.error(error);
150    }
151  };
152}());
153
154/**
155 * グローバル空間への公開
156 * application.js等から参照可能にするため、windowオブジェクトに登録します。
157 */
158window.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.