@nodebb/nodebb-plugin-reactions 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/library.js CHANGED
@@ -3,6 +3,7 @@
3
3
  const _ = require.main.require('lodash');
4
4
  const meta = require.main.require('./src/meta');
5
5
  const user = require.main.require('./src/user');
6
+ const posts = require.main.require('./src/posts');
6
7
  const db = require.main.require('./src/database');
7
8
  const routesHelpers = require.main.require('./src/routes/helpers');
8
9
  const websockets = require.main.require('./src/socket.io/index');
@@ -139,9 +140,9 @@ ReactionsPlugin.deleteReactions = async function (hookData) {
139
140
  const keys = [];
140
141
  pidsReactions.forEach((reactions, index) => {
141
142
  keys.push(
142
- ...reactions.map(reaction => `pid:${pid}:reaction:${reaction}`),
143
+ ...reactions.map(reaction => `pid:${pids[index]}:reaction:${reaction}`),
143
144
  `pid:${pids[index]}:reactions`,
144
- )
145
+ );
145
146
  });
146
147
 
147
148
  await db.deleteAll(keys);
@@ -176,6 +177,20 @@ async function sendEvent(data, eventName) {
176
177
  }
177
178
  }
178
179
 
180
+ async function getReactionReputation(reaction) {
181
+ const settings = await meta.settings.get('reactions');
182
+ const reactionsReps = settings['reaction-reputations'] || [];
183
+ const foundReaction = reactionsReps.find(r => r.reaction === reaction);
184
+ return foundReaction ? parseInt(foundReaction.reputation, 10) || 0 : 0;
185
+ }
186
+
187
+ async function giveOwnerReactionReputation(reactionReputation, pid) {
188
+ const ownerUid = await posts.getPostField(pid, 'uid');
189
+ if (parseInt(ownerUid, 10) > 0) {
190
+ await user.incrementUserReputationBy(ownerUid, reactionReputation);
191
+ }
192
+ }
193
+
179
194
  SocketPlugins.reactions = {
180
195
  addPostReaction: async function (socket, data) {
181
196
  if (!socket.uid) {
@@ -191,10 +206,11 @@ SocketPlugins.reactions = {
191
206
  try {
192
207
  const settings = await meta.settings.get('reactions');
193
208
  const maximumReactions = settings.maximumReactions || DEFAULT_MAX_EMOTES;
194
-
195
- const [totalReactions, isMember] = await Promise.all([
209
+ const [totalReactions, isMember, alreadyReacted, reactionReputation] = await Promise.all([
196
210
  db.setCount(`pid:${data.pid}:reactions`),
197
211
  db.isSetMember(`pid:${data.pid}:reactions`, data.reaction),
212
+ db.isSetMember(`pid:${data.pid}:reaction:${data.reaction}`, socket.uid),
213
+ getReactionReputation(data.reaction),
198
214
  ]);
199
215
 
200
216
  if (!isMember && totalReactions >= maximumReactions) {
@@ -206,6 +222,10 @@ SocketPlugins.reactions = {
206
222
  db.setAdd(`pid:${data.pid}:reaction:${data.reaction}`, socket.uid),
207
223
  ]);
208
224
 
225
+ if (!alreadyReacted && reactionReputation > 0) {
226
+ await giveOwnerReactionReputation(reactionReputation, data.pid);
227
+ }
228
+
209
229
  await sendEvent(data, 'event:reactions.addPostReaction');
210
230
  } catch (e) {
211
231
  console.error(e);
@@ -223,13 +243,21 @@ SocketPlugins.reactions = {
223
243
  data.uid = socket.uid;
224
244
 
225
245
  try {
226
- await db.setRemove(`pid:${data.pid}:reaction:${data.reaction}`, socket.uid);
246
+ const [hasReacted, reactionReputation] = await Promise.all([
247
+ db.isSetMember(`pid:${data.pid}:reaction:${data.reaction}`, socket.uid),
248
+ getReactionReputation(data.reaction),
249
+ ]);
250
+ if (hasReacted) {
251
+ await db.setRemove(`pid:${data.pid}:reaction:${data.reaction}`, socket.uid);
252
+ }
227
253
 
228
254
  const reactionCount = await db.setCount(`pid:${data.pid}:reaction:${data.reaction}`);
229
255
  if (reactionCount === 0) {
230
256
  await db.setRemove(`pid:${data.pid}:reactions`, data.reaction);
231
257
  }
232
-
258
+ if (hasReacted && reactionReputation > 0) {
259
+ await giveOwnerReactionReputation(-reactionReputation, data.pid);
260
+ }
233
261
  await sendEvent(data, 'event:reactions.removePostReaction');
234
262
  } catch (e) {
235
263
  console.error(e);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodebb/nodebb-plugin-reactions",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "nbbpm": {
5
5
  "compatibility": "^1.19.7"
6
6
  },
@@ -31,7 +31,7 @@
31
31
  "name": "Barış Soner Uşaklı",
32
32
  "email": "baris@nodebb.org",
33
33
  "url": "https://github.com/barisusakli"
34
- }
34
+ }
35
35
  ],
36
36
  "dependencies": {},
37
37
  "peerDependencies": {
package/public/admin.js CHANGED
@@ -1,9 +1,42 @@
1
1
  'use strict';
2
2
 
3
- define('admin/plugins/reactions', ['settings', 'alerts'], function (Settings, alerts) {
3
+ define('admin/plugins/reactions', [
4
+ 'settings', 'alerts', 'hooks', 'emoji-dialog', 'emoji',
5
+ ], function (Settings, alerts, hooks, emojiDialog, emoji) {
4
6
  var ACP = {};
5
7
  ACP.init = function () {
6
- Settings.load('reactions', $('.reactions-settings'));
8
+ emoji.init(function () {
9
+ Settings.load('reactions', $('.reactions-settings'), onSettingsLoaded);
10
+ });
11
+ };
12
+
13
+ function onSettingsLoaded() {
14
+ hooks.on('action:settings.sorted-list.parse', function (data) {
15
+ const reactionEl = data.itemHtml.find('[data-reaction]');
16
+ if (reactionEl.length) {
17
+ const reaction = reactionEl.attr('data-reaction');
18
+ if (reaction) {
19
+ const foundEmoji = emoji.table[reaction]
20
+ if (foundEmoji) {
21
+ reactionEl.html(emoji.buildEmoji(foundEmoji));
22
+ }
23
+ }
24
+ }
25
+ });
26
+
27
+ hooks.on('action:settings.sorted-list.modal', function (data) {
28
+ const { modal } = data;
29
+ modal.removeAttr('tabindex');
30
+ modal.find('#reaction').off('click').on('click', function () {
31
+ emojiDialog.toggle(modal.find('#reaction')[0], function (_, name, dialog) {
32
+ emojiDialog.dialogActions.close(dialog);
33
+ modal.find('#reaction').val(name);
34
+ });
35
+ });
36
+ modal.off('hide.bs.modal').on('hide.bs.modal', function () {
37
+ emojiDialog.dialogActions.close($('#emoji-dialog'));
38
+ });
39
+ });
7
40
 
8
41
  $('#save').on('click', function () {
9
42
  Settings.save('reactions', $('.reactions-settings'), function () {
@@ -15,7 +48,7 @@ define('admin/plugins/reactions', ['settings', 'alerts'], function (Settings, a
15
48
  });
16
49
  });
17
50
  });
18
- };
51
+ }
19
52
 
20
53
  return ACP;
21
54
  });
@@ -0,0 +1,10 @@
1
+ <form>
2
+ <div class="form-group">
3
+ <label for="reaction">Reaction</label>
4
+ <input type="text" id="reaction" name="reaction" class="form-control" placeholder="Reaction" />
5
+ </div>
6
+ <div class="form-group">
7
+ <label for="reputation">Reputation</label>
8
+ <input type="number" id="reputation" name="reputation" class="form-control" placeholder="reputation" />
9
+ </div>
10
+ </form>
@@ -0,0 +1,12 @@
1
+ <li data-type="item" class="list-group-item">
2
+ <div class="row">
3
+ <div class="col-xs-9">
4
+ <span data-reaction="{reaction}"></span><strong> {reaction}</strong><br />
5
+ <small>Reputation: {reputation}</small>
6
+ </div>
7
+ <div class="col-xs-3 text-right">
8
+ <button type="button" data-type="edit" class="btn btn-info">Edit</button>
9
+ <button type="button" data-type="remove" class="btn btn-danger">Delete</button>
10
+ </div>
11
+ </div>
12
+ </li>
@@ -1,14 +1,30 @@
1
- <div class="row">
2
- <div class="col-sm-2 col-xs-12 settings-header">Reactions plugin settings</div>
3
- <div class="col-sm-10 col-xs-12">
4
- <form role="form" class="reactions-settings">
1
+ <form role="form" class="reactions-settings">
2
+ <div class="row">
3
+ <div class="col-sm-2 col-xs-12 settings-header">Reactions plugin settings</div>
4
+ <div class="col-sm-10 col-xs-12">
5
5
  <div class="form-group">
6
6
  <label>Maximum unique reactions per post</label>
7
7
  <input type="text" class="form-control" id="maximumReactions" name="maximumReactions">
8
8
  </div>
9
- </form>
9
+ </div>
10
10
  </div>
11
- </div>
11
+ <div class="row">
12
+ <div class="col-sm-2 col-xs-12 settings-header">Reaction Reputations (Optional)</div>
13
+ <div class="col-sm-10 col-xs-12">
14
+ <p class="help-text">
15
+ You can assign a reputation to individual reactions. When a reaction is applied to a post, the owner of that post will get this reputation.
16
+ </p>
17
+ <div class="form-group" data-type="sorted-list" data-sorted-list="reaction-reputations" data-item-template="admin/plugins/reactions/partials/sorted-list/emoji-item" data-form-template="admin/plugins/reactions/partials/sorted-list/emoji-form">
18
+ <ul data-type="list" class="list-group"></ul>
19
+ <button type="button" data-type="add" class="btn btn-info">Add Item</button>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ </form>
24
+
25
+
26
+
27
+
12
28
 
13
29
  <button id="save" class="floating-button mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored">
14
30
  <i class="material-icons">save</i>