nodebb-plugin-composer-default 10.2.50 → 10.3.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-composer-default",
3
- "version": "10.2.50",
3
+ "version": "10.3.0",
4
4
  "description": "Default composer for NodeBB",
5
5
  "main": "library.js",
6
6
  "repository": {
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "readmeFilename": "README.md",
28
28
  "nbbpm": {
29
- "compatibility": "^4.0.0"
29
+ "compatibility": "^4.5.0"
30
30
  },
31
31
  "dependencies": {
32
32
  "screenfull": "^5.0.2",
@@ -41,7 +41,6 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
41
41
  });
42
42
 
43
43
  drafts.migrateGuest();
44
- drafts.migrateThumbs(...arguments);
45
44
  };
46
45
 
47
46
  function getStorage(uid) {
@@ -100,6 +99,7 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
100
99
  draftData.tags = tags;
101
100
  draftData.title = title;
102
101
  draftData.cid = postData.cid;
102
+ draftData.thumbs = postData.thumbs || [];
103
103
  } else if (postData.action === 'posts.reply') {
104
104
  // new reply only
105
105
  draftData.title = postData.title;
@@ -108,6 +108,7 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
108
108
  } else if (postData.action === 'posts.edit') {
109
109
  draftData.pid = postData.pid;
110
110
  draftData.title = title || postData.title;
111
+ draftData.thumbs = postData.thumbs || [];
111
112
  }
112
113
  if (!app.user.uid) {
113
114
  draftData.handle = postContainer.find('input.handle').val();
@@ -208,26 +209,6 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
208
209
  }
209
210
  };
210
211
 
211
- drafts.migrateThumbs = function (postContainer, postData) {
212
- if (!app.uid) {
213
- return;
214
- }
215
-
216
- // If any thumbs were uploaded, migrate them to this new composer's uuid
217
- const newUUID = postContainer.attr('data-uuid');
218
- const draft = drafts.get(postData.save_id);
219
-
220
- if (draft && draft.uuid) {
221
- api.put(`/topics/${draft.uuid}/thumbs`, {
222
- tid: newUUID,
223
- }).then(() => {
224
- require(['composer'], function (composer) {
225
- composer.updateThumbCount(newUUID, postContainer);
226
- });
227
- });
228
- }
229
- };
230
-
231
212
  drafts.listAvailable = function () {
232
213
  const available = drafts.getList('available');
233
214
  return available.map(drafts.get).filter(Boolean);
@@ -286,6 +267,7 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
286
267
  title: utils.escapeHTML(draft.title),
287
268
  body: draft.text,
288
269
  tags: String(draft.tags || '').split(','),
270
+ thumbs: draft.thumbs || [],
289
271
  });
290
272
  } else if (draft.action === 'posts.reply') {
291
273
  api.get('/topics/' + draft.tid, {}, function (err, topicObj) {
@@ -307,6 +289,7 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
307
289
  pid: draft.pid,
308
290
  title: draft.title ? utils.escapeHTML(draft.title) : undefined,
309
291
  body: draft.text,
292
+ thumbs: draft.thumbs || [],
310
293
  });
311
294
  }
312
295
  });
@@ -28,8 +28,8 @@ define('composer/formatting', [
28
28
  const composerObj = composer.posts[uuid];
29
29
 
30
30
  if (composerObj.action === 'topics.post' || (composerObj.action === 'posts.edit' && composerObj.isMain)) {
31
- topicThumbs.modal.open({ id: uuid, pid: composerObj.pid }).then(() => {
32
- postContainer.trigger('thumb.uploaded'); // toggle draft save
31
+ topicThumbs.modal.open({ id: uuid, postData: composerObj }).then(() => {
32
+ postContainer.trigger('thumb.uploaded');
33
33
 
34
34
  // Update client-side with count
35
35
  composer.updateThumbCount(uuid, postContainer);
@@ -19,7 +19,7 @@ define('composer/uploads', [
19
19
  initializePaste(post_uuid);
20
20
 
21
21
  addChangeHandlers(post_uuid);
22
- addTopicThumbHandlers(post_uuid);
22
+
23
23
  translator.translate('[[modules:composer.uploading, ' + 0 + '%]]', function (translated) {
24
24
  uploadingText = translated;
25
25
  });
@@ -37,36 +37,6 @@ define('composer/uploads', [
37
37
  });
38
38
  }
39
39
 
40
- function addTopicThumbHandlers(post_uuid) {
41
- var postContainer = $('.composer[data-uuid="' + post_uuid + '"]');
42
-
43
- postContainer.on('click', '.topic-thumb-clear-btn', function (e) {
44
- postContainer.find('input#topic-thumb-url').val('').trigger('change');
45
- resetInputFile(postContainer.find('input#topic-thumb-file'));
46
- $(this).addClass('hide');
47
- e.preventDefault();
48
- });
49
-
50
- postContainer.on('paste change keypress', 'input#topic-thumb-url', function () {
51
- var urlEl = $(this);
52
- setTimeout(function () {
53
- var url = urlEl.val();
54
- if (url) {
55
- postContainer.find('.topic-thumb-clear-btn').removeClass('hide');
56
- } else {
57
- resetInputFile(postContainer.find('input#topic-thumb-file'));
58
- postContainer.find('.topic-thumb-clear-btn').addClass('hide');
59
- }
60
- postContainer.find('img.topic-thumb-preview').attr('src', url);
61
- }, 100);
62
- });
63
- }
64
-
65
- function resetInputFile($el) {
66
- $el.wrap('<form />').closest('form').get(0).reset();
67
- $el.unwrap();
68
- }
69
-
70
40
  function initializeDragAndDrop(post_uuid) {
71
41
  var postContainer = $('.composer[data-uuid="' + post_uuid + '"]');
72
42
  uploadHelpers.handleDragDrop({
@@ -201,6 +201,7 @@ define('composer', [
201
201
  title: data.title || '',
202
202
  body: data.body || '',
203
203
  tags: data.tags || [],
204
+ thumbs: data.thumbs || [],
204
205
  modified: !!((data.title && data.title.length) || (data.body && data.body.length)),
205
206
  isMain: true,
206
207
  };
@@ -417,7 +418,7 @@ define('composer', [
417
418
  handleHelp(postContainer);
418
419
  handleSearch(postContainer);
419
420
  focusElements(postContainer);
420
- if (postData.action === 'posts.edit') {
421
+ if (postData.action === 'posts.edit' || postData.action === 'topics.post') {
421
422
  composer.updateThumbCount(post_uuid, postContainer);
422
423
  }
423
424
 
@@ -736,6 +737,7 @@ define('composer', [
736
737
  thumb: thumbEl.val() || '',
737
738
  cid: categoryList.getSelectedCid(),
738
739
  tags: tags.getTags(post_uuid),
740
+ thumbs: postData.thumbs || [],
739
741
  timestamp: scheduler.getTimestamp(),
740
742
  };
741
743
  } else if (action === 'posts.reply') {
@@ -756,7 +758,7 @@ define('composer', [
756
758
  handle: handleEl ? handleEl.val() : undefined,
757
759
  content: bodyEl.val(),
758
760
  title: titleEl.val(),
759
- thumb: thumbEl.val() || '',
761
+ thumbs: postData.thumbs || [],
760
762
  tags: tags.getTags(post_uuid),
761
763
  timestamp: scheduler.getTimestamp(),
762
764
  };
@@ -883,20 +885,12 @@ define('composer', [
883
885
 
884
886
  composer.updateThumbCount = function (uuid, postContainer) {
885
887
  const composerObj = composer.posts[uuid];
886
- if (composerObj.action === 'topics.post' || (composerObj.action === 'posts.edit' && composerObj.isMain)) {
887
- const calls = [
888
- topicThumbs.get(uuid),
889
- ];
890
- if (composerObj.pid) {
891
- calls.push(topicThumbs.getByPid(composerObj.pid));
892
- }
893
- Promise.all(calls).then((thumbs) => {
894
- const thumbCount = thumbs.flat().length;
895
- const formatEl = postContainer.find('[data-format="thumbs"]');
896
- formatEl.find('.badge')
897
- .text(thumbCount)
898
- .toggleClass('hidden', !thumbCount);
899
- });
888
+ if (composerObj && (composerObj.action === 'topics.post' || (composerObj.action === 'posts.edit' && composerObj.isMain))) {
889
+ const thumbCount = composerObj.thumbs ? composerObj.thumbs.length : 0;
890
+ const formatEl = postContainer.find('[data-format="thumbs"]');
891
+ formatEl.find('.badge')
892
+ .text(thumbCount)
893
+ .toggleClass('hidden', !thumbCount);
900
894
  }
901
895
  };
902
896
 
@@ -6,7 +6,7 @@
6
6
  {{{ else }}}
7
7
  {{{ if (./visibility.desktop && ((isTopicOrMain && ./visibility.main) || (!isTopicOrMain && ./visibility.reply))) }}}
8
8
  {{{ if ./dropdownItems.length }}}
9
- <li class="dropdown bottom-sheet" title="{./title}">
9
+ <li class="dropdown dropdown-left bottom-sheet" title="{./title}">
10
10
  <button class="btn btn-sm btn-link text-reset" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="{./title}">
11
11
  <i class="{./className}"></i>
12
12
  </button>
package/websockets.js CHANGED
@@ -19,9 +19,8 @@ Sockets.push = async function (socket, pid) {
19
19
  throw new Error('[[error:invalid-pid]]');
20
20
  }
21
21
 
22
- const [topic, tags, isMain] = await Promise.all([
22
+ const [topic, isMain] = await Promise.all([
23
23
  topics.getTopicDataByPid(pid),
24
- topics.getTopicTags(postData.tid),
25
24
  posts.isMain(pid),
26
25
  ]);
27
26
 
@@ -35,8 +34,8 @@ Sockets.push = async function (socket, pid) {
35
34
  handle: parseInt(meta.config.allowGuestHandles, 10) ? postData.handle : undefined,
36
35
  body: postData.sourceContent || postData.content,
37
36
  title: topic.title,
38
- thumb: topic.thumb,
39
- tags: tags,
37
+ thumbs: topic.thumbs,
38
+ tags: topic.tags.map(t => t.value),
40
39
  isMain: isMain,
41
40
  timestamp: postData.timestamp,
42
41
  });
package/.jshintrc DELETED
@@ -1,86 +0,0 @@
1
- {
2
- // JSHint Default Configuration File (as on JSHint website)
3
- // See http://jshint.com/docs/ for more details
4
-
5
- "maxerr" : 50, // {int} Maximum error before stopping
6
-
7
- // Enforcing
8
- "bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.)
9
- "camelcase" : false, // true: Identifiers must be in camelCase
10
- "curly" : true, // true: Require {} for every new block or scope
11
- "eqeqeq" : true, // true: Require triple equals (===) for comparison
12
- "forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty()
13
- "immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
14
- "indent" : 4, // {int} Number of spaces to use for indentation
15
- "latedef" : false, // true: Require variables/functions to be defined before being used
16
- "newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()`
17
- "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
18
- "noempty" : true, // true: Prohibit use of empty blocks
19
- "nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment)
20
- "plusplus" : false, // true: Prohibit use of `++` & `--`
21
- "quotmark" : false, // Quotation mark consistency:
22
- // false : do nothing (default)
23
- // true : ensure whatever is used is consistent
24
- // "single" : require single quotes
25
- // "double" : require double quotes
26
- "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
27
- "unused" : true, // true: Require all defined variables be used
28
- "strict" : true, // true: Requires all functions run in ES5 Strict Mode
29
- "trailing" : false, // true: Prohibit trailing whitespaces
30
- "maxparams" : false, // {int} Max number of formal params allowed per function
31
- "maxdepth" : false, // {int} Max depth of nested blocks (within functions)
32
- "maxstatements" : false, // {int} Max number statements per function
33
- "maxcomplexity" : false, // {int} Max cyclomatic complexity per function
34
- "maxlen" : false, // {int} Max number of characters per line
35
-
36
- // Relaxing
37
- "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
38
- "boss" : false, // true: Tolerate assignments where comparisons would be expected
39
- "debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
40
- "eqnull" : false, // true: Tolerate use of `== null`
41
- "es5" : false, // true: Allow ES5 syntax (ex: getters and setters)
42
- "esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`)
43
- "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
44
- // (ex: `for each`, multiple try/catch, function expression…)
45
- "evil" : false, // true: Tolerate use of `eval` and `new Function()`
46
- "expr" : false, // true: Tolerate `ExpressionStatement` as Programs
47
- "funcscope" : false, // true: Tolerate defining variables inside control statements"
48
- "globalstrict" : false, // true: Allow global "use strict" (also enables 'strict')
49
- "iterator" : false, // true: Tolerate using the `__iterator__` property
50
- "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
51
- "laxbreak" : false, // true: Tolerate possibly unsafe line breakings
52
- "laxcomma" : false, // true: Tolerate comma-first style coding
53
- "loopfunc" : false, // true: Tolerate functions being defined in loops
54
- "multistr" : false, // true: Tolerate multi-line strings
55
- "proto" : false, // true: Tolerate using the `__proto__` property
56
- "scripturl" : false, // true: Tolerate script-targeted URLs
57
- "smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment
58
- "shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
59
- "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
60
- "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
61
- "validthis" : false, // true: Tolerate using this in a non-constructor function
62
-
63
- // Environments
64
- "browser" : true, // Web Browser (window, document, etc)
65
- "couch" : false, // CouchDB
66
- "devel" : true, // Development/debugging (alert, confirm, etc)
67
- "dojo" : false, // Dojo Toolkit
68
- "jquery" : true, // jQuery
69
- "mootools" : false, // MooTools
70
- "node" : true, // Node.js
71
- "nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
72
- "prototypejs" : false, // Prototype and Scriptaculous
73
- "rhino" : false, // Rhino
74
- "worker" : false, // Web Workers
75
- "wsh" : false, // Windows Scripting Host
76
- "yui" : false, // Yahoo User Interface
77
-
78
- // Legacy
79
- "nomen" : false, // true: Prohibit dangling `_` in variables
80
- "onevar" : false, // true: Allow only one `var` statement per function
81
- "passfail" : false, // true: Stop on first error
82
- "white" : false, // true: Check against strict whitespace and indentation rules
83
-
84
- // Custom Globals
85
- "globals" : {} // additional predefined global variables
86
- }
@@ -1,6 +0,0 @@
1
- {
2
- "extends": "nodebb/public",
3
- "rules": {
4
- "no-cond-assign": ["error", "except-parens"]
5
- }
6
- }