nodebb-plugin-composer-default 10.0.17 → 10.0.19
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,7 +3,6 @@
|
|
|
3
3
|
const url = require('url');
|
|
4
4
|
|
|
5
5
|
const nconf = require.main.require('nconf');
|
|
6
|
-
const winston = require.main.require('winston');
|
|
7
6
|
const validator = require('validator');
|
|
8
7
|
|
|
9
8
|
const plugins = require.main.require('./src/plugins');
|
|
@@ -14,6 +13,7 @@ const user = require.main.require('./src/user');
|
|
|
14
13
|
const meta = require.main.require('./src/meta');
|
|
15
14
|
const privileges = require.main.require('./src/privileges');
|
|
16
15
|
const translator = require.main.require('./src/translator');
|
|
16
|
+
const utils = require.main.require('./src/utils');
|
|
17
17
|
const helpers = require.main.require('./src/controllers/helpers');
|
|
18
18
|
const SocketPlugins = require.main.require('./src/socket.io/plugins');
|
|
19
19
|
const socketMethods = require('./websockets');
|
|
@@ -164,7 +164,7 @@ plugin.filterComposerBuild = async function (hookData) {
|
|
|
164
164
|
|
|
165
165
|
const isEditing = !!req.query.pid;
|
|
166
166
|
const isGuestPost = postData && parseInt(postData.uid, 10) === 0;
|
|
167
|
-
const save_id = generateSaveId(req);
|
|
167
|
+
const save_id = utils.generateSaveId(req.uid);
|
|
168
168
|
const discardRoute = generateDiscardRoute(req, topicData);
|
|
169
169
|
const body = await generateBody(req, postData);
|
|
170
170
|
|
|
@@ -251,16 +251,6 @@ async function generateBody(req, postData) {
|
|
|
251
251
|
return postData ? postData.content : '';
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
function generateSaveId(req) {
|
|
255
|
-
if (req.query.cid) {
|
|
256
|
-
return ['composer', req.uid, 'cid', req.query.cid].join(':');
|
|
257
|
-
} else if (req.query.tid) {
|
|
258
|
-
return ['composer', req.uid, 'tid', req.query.tid].join(':');
|
|
259
|
-
} else if (req.query.pid) {
|
|
260
|
-
return ['composer', req.uid, 'pid', req.query.pid].join(':');
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
254
|
async function getPostData(req) {
|
|
265
255
|
if (!req.query.pid && !req.query.toPid) {
|
|
266
256
|
return null;
|
package/package.json
CHANGED
package/static/lib/client.js
CHANGED
|
@@ -30,7 +30,7 @@ $(document).ready(function () {
|
|
|
30
30
|
$(window).on('action:composer.post.edit', function (ev, data) {
|
|
31
31
|
if (config['composer-default'].composeRouteEnabled !== 'on') {
|
|
32
32
|
require(['composer'], function (composer) {
|
|
33
|
-
composer.editPost(data.pid);
|
|
33
|
+
composer.editPost({ pid: data.pid });
|
|
34
34
|
});
|
|
35
35
|
} else {
|
|
36
36
|
ajaxify.go('compose?pid=' + data.pid);
|
|
@@ -40,7 +40,12 @@ $(document).ready(function () {
|
|
|
40
40
|
$(window).on('action:composer.post.new', function (ev, data) {
|
|
41
41
|
if (config['composer-default'].composeRouteEnabled !== 'on') {
|
|
42
42
|
require(['composer'], function (composer) {
|
|
43
|
-
composer.newReply(
|
|
43
|
+
composer.newReply({
|
|
44
|
+
tid: data.tid,
|
|
45
|
+
pid: data.pid,
|
|
46
|
+
title: data.topicName,
|
|
47
|
+
body: data.text,
|
|
48
|
+
});
|
|
44
49
|
});
|
|
45
50
|
} else {
|
|
46
51
|
ajaxify.go(
|
|
@@ -56,7 +61,15 @@ $(document).ready(function () {
|
|
|
56
61
|
if (config['composer-default'].composeRouteEnabled !== 'on') {
|
|
57
62
|
require(['composer'], function (composer) {
|
|
58
63
|
var topicUUID = composer.findByTid(data.tid);
|
|
59
|
-
composer.addQuote(
|
|
64
|
+
composer.addQuote({
|
|
65
|
+
tid: data.tid,
|
|
66
|
+
toPid: data.pid,
|
|
67
|
+
selectedPid: data.selectedPid,
|
|
68
|
+
title: data.topicName,
|
|
69
|
+
username: data.username,
|
|
70
|
+
body: data.text,
|
|
71
|
+
uuid: topicUUID,
|
|
72
|
+
});
|
|
60
73
|
});
|
|
61
74
|
} else {
|
|
62
75
|
ajaxify.go('compose?tid=' + data.tid + '&toPid=' + data.pid + '"ed=1&username=' + data.username);
|
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
const drafts = {};
|
|
5
|
+
const draftSaveDelay = 2000;
|
|
6
6
|
drafts.init = function (postContainer, postData) {
|
|
7
|
-
|
|
7
|
+
const draftIconEl = postContainer.find('.draft-icon');
|
|
8
8
|
function doSaveDraft() {
|
|
9
|
+
if (!postData.save_id) {
|
|
10
|
+
postData.save_id = utils.generateSaveId(app.user.uid);
|
|
11
|
+
}
|
|
9
12
|
// Post is modified, save to list of opened drafts
|
|
10
|
-
drafts.
|
|
11
|
-
drafts.
|
|
13
|
+
drafts.addToDraftList('available', postData.save_id);
|
|
14
|
+
drafts.addToDraftList('open', postData.save_id);
|
|
12
15
|
saveDraft(postContainer, draftIconEl, postData);
|
|
13
16
|
}
|
|
14
17
|
|
|
15
|
-
postContainer.on('keyup', 'textarea, input.handle, input.title', utils.debounce(doSaveDraft,
|
|
16
|
-
postContainer.on('click', 'input[type="checkbox"]', utils.debounce(doSaveDraft,
|
|
18
|
+
postContainer.on('keyup', 'textarea, input.handle, input.title', utils.debounce(doSaveDraft, draftSaveDelay));
|
|
19
|
+
postContainer.on('click', 'input[type="checkbox"]', utils.debounce(doSaveDraft, draftSaveDelay));
|
|
20
|
+
postContainer.on('click', '[component="category/list"] [data-cid]', utils.debounce(doSaveDraft, draftSaveDelay));
|
|
21
|
+
postContainer.on('itemAdded', '.tags', utils.debounce(doSaveDraft, draftSaveDelay));
|
|
17
22
|
postContainer.on('thumb.uploaded', doSaveDraft);
|
|
18
23
|
|
|
19
24
|
draftIconEl.on('animationend', function () {
|
|
@@ -21,19 +26,10 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
|
|
|
21
26
|
});
|
|
22
27
|
|
|
23
28
|
$(window).on('unload', function () {
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
open = localStorage.getItem('drafts:open');
|
|
28
|
-
open = JSON.parse(open) || [];
|
|
29
|
-
} catch (e) {
|
|
30
|
-
console.warn('[composer/drafts] Could not read list of open/available drafts');
|
|
31
|
-
open = [];
|
|
32
|
-
}
|
|
29
|
+
// remove all drafts from the open list
|
|
30
|
+
const open = drafts.getList('open');
|
|
33
31
|
if (open.length) {
|
|
34
|
-
open.forEach(
|
|
35
|
-
drafts.updateVisibility('open', save_id);
|
|
36
|
-
});
|
|
32
|
+
open.forEach(save_id => drafts.removeFromDraftList('open', save_id));
|
|
37
33
|
}
|
|
38
34
|
});
|
|
39
35
|
|
|
@@ -46,62 +42,72 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
|
|
|
46
42
|
}
|
|
47
43
|
|
|
48
44
|
drafts.get = function (save_id) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
var draft = {
|
|
52
|
-
text: storage.getItem(save_id),
|
|
53
|
-
save_id: save_id,
|
|
54
|
-
};
|
|
55
|
-
['cid', 'title', 'tags', 'uuid', 'timestamp'].forEach(function (key) {
|
|
56
|
-
const value = storage.getItem(save_id + ':' + key);
|
|
57
|
-
if (value) {
|
|
58
|
-
draft[key] = value;
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
if (!parseInt(uid, 10)) {
|
|
62
|
-
draft.handle = storage.getItem(save_id + ':handle');
|
|
45
|
+
if (!save_id) {
|
|
46
|
+
return null;
|
|
63
47
|
}
|
|
64
|
-
|
|
65
|
-
|
|
48
|
+
const uid = save_id.split(':')[1];
|
|
49
|
+
const storage = getStorage(uid);
|
|
50
|
+
try {
|
|
51
|
+
const draftJson = storage.getItem(save_id);
|
|
52
|
+
const draft = JSON.parse(draftJson) || null;
|
|
53
|
+
if (!draft) {
|
|
54
|
+
throw new Error(`can't parse draft json for ${save_id}`);
|
|
55
|
+
}
|
|
56
|
+
draft.save_id = save_id;
|
|
57
|
+
if (draft.timestamp) {
|
|
58
|
+
draft.timestampISO = utils.toISOString(draft.timestamp);
|
|
59
|
+
}
|
|
60
|
+
$(window).trigger('action:composer.drafts.get', {
|
|
61
|
+
save_id: save_id,
|
|
62
|
+
draft: draft,
|
|
63
|
+
storage: storage,
|
|
64
|
+
});
|
|
65
|
+
return draft;
|
|
66
|
+
} catch (e) {
|
|
67
|
+
console.warn(`[composer/drafts] Could not get draft ${save_id}, removing`);
|
|
68
|
+
drafts.removeFromDraftList('available');
|
|
69
|
+
drafts.removeFromDraftList('open');
|
|
70
|
+
return null;
|
|
66
71
|
}
|
|
67
|
-
|
|
68
|
-
$(window).trigger('action:composer.drafts.get', {
|
|
69
|
-
save_id: save_id,
|
|
70
|
-
draft: draft,
|
|
71
|
-
storage: storage,
|
|
72
|
-
});
|
|
73
|
-
return draft;
|
|
74
72
|
};
|
|
75
73
|
|
|
76
74
|
function saveDraft(postContainer, draftIconEl, postData) {
|
|
77
75
|
if (canSave(app.user.uid ? 'localStorage' : 'sessionStorage') && postData && postData.save_id && postContainer.length) {
|
|
78
76
|
const titleEl = postContainer.find('input.title');
|
|
79
77
|
const title = titleEl && titleEl.val();
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (postData.hasOwnProperty('cid') && !postData.save_id.endsWith(':cid:' + postData.cid)) {
|
|
84
|
-
// A new cid was selected, the save_id needs updating
|
|
85
|
-
drafts.removeDraft(postData.save_id); // First, delete the old draft
|
|
86
|
-
postData.save_id = postData.save_id.replace(/cid:\d+$/, 'cid:' + postData.cid); // then create a new save_id
|
|
87
|
-
}
|
|
78
|
+
const raw = postContainer.find('textarea').val();
|
|
79
|
+
const storage = getStorage(app.user.uid);
|
|
88
80
|
|
|
89
81
|
if (raw.length || (title && title.length)) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
82
|
+
const draftData = {
|
|
83
|
+
save_id: postData.save_id,
|
|
84
|
+
action: postData.action,
|
|
85
|
+
text: raw,
|
|
86
|
+
uuid: postContainer.attr('data-uuid'),
|
|
87
|
+
timestamp: Date.now(),
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
if (postData.action === 'topics.post') {
|
|
95
91
|
// New topic only
|
|
96
92
|
const tags = postContainer.find('input.tags').val();
|
|
97
|
-
|
|
98
|
-
|
|
93
|
+
draftData.tags = tags;
|
|
94
|
+
draftData.title = title;
|
|
95
|
+
draftData.cid = postData.cid;
|
|
96
|
+
} else if (postData.action === 'posts.reply') {
|
|
97
|
+
// new reply only
|
|
98
|
+
draftData.title = postData.title;
|
|
99
|
+
draftData.tid = postData.tid;
|
|
100
|
+
draftData.toPid = postData.toPid;
|
|
101
|
+
} else if (postData.action === 'posts.edit') {
|
|
102
|
+
draftData.pid = postData.pid;
|
|
99
103
|
}
|
|
100
104
|
if (!app.user.uid) {
|
|
101
|
-
|
|
102
|
-
storage.setItem(postData.save_id + ':handle', handle);
|
|
105
|
+
draftData.handle = postContainer.find('input.handle').val();
|
|
103
106
|
}
|
|
104
107
|
|
|
108
|
+
// save all draft data into single item as json
|
|
109
|
+
storage.setItem(postData.save_id, JSON.stringify(draftData));
|
|
110
|
+
|
|
105
111
|
$(window).trigger('action:composer.drafts.save', {
|
|
106
112
|
storage: storage,
|
|
107
113
|
postData: postData,
|
|
@@ -120,54 +126,64 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
|
|
|
120
126
|
}
|
|
121
127
|
|
|
122
128
|
// Remove save_id from list of open and available drafts
|
|
123
|
-
drafts.
|
|
124
|
-
drafts.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
+
drafts.removeFromDraftList('available', save_id);
|
|
130
|
+
drafts.removeFromDraftList('open', save_id);
|
|
131
|
+
const uid = save_id.split(':')[1];
|
|
132
|
+
const storage = getStorage(uid);
|
|
133
|
+
storage.removeItem(save_id);
|
|
134
|
+
|
|
129
135
|
$(window).trigger('action:composer.drafts.remove', {
|
|
130
136
|
storage: storage,
|
|
131
137
|
save_id: save_id,
|
|
132
138
|
});
|
|
133
139
|
};
|
|
134
140
|
|
|
135
|
-
drafts.
|
|
136
|
-
if (!canSave(app.user.uid ? 'localStorage' : 'sessionStorage') || !save_id) {
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
var open = [];
|
|
141
|
+
drafts.getList = function (set) {
|
|
140
142
|
try {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
+
const draftIds = localStorage.getItem(`drafts:${set}`);
|
|
144
|
+
return JSON.parse(draftIds) || [];
|
|
143
145
|
} catch (e) {
|
|
144
|
-
console.warn('[composer/drafts] Could not read list of
|
|
145
|
-
|
|
146
|
+
console.warn('[composer/drafts] Could not read list of available drafts');
|
|
147
|
+
return [];
|
|
146
148
|
}
|
|
147
|
-
|
|
149
|
+
};
|
|
148
150
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
drafts.addToDraftList = function (set, save_id) {
|
|
152
|
+
if (!canSave(app.user.uid ? 'localStorage' : 'sessionStorage') || !save_id) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const list = drafts.getList(set);
|
|
156
|
+
if (!list.includes(save_id)) {
|
|
157
|
+
list.push(save_id);
|
|
158
|
+
localStorage.setItem('drafts:' + set, JSON.stringify(list));
|
|
159
|
+
}
|
|
160
|
+
};
|
|
154
161
|
|
|
155
|
-
|
|
162
|
+
drafts.removeFromDraftList = function (set, save_id) {
|
|
163
|
+
if (!canSave(app.user.uid ? 'localStorage' : 'sessionStorage') || !save_id) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const list = drafts.getList(set);
|
|
167
|
+
if (list.includes(save_id)) {
|
|
168
|
+
list.splice(list.indexOf(save_id), 1);
|
|
169
|
+
localStorage.setItem('drafts:' + set, JSON.stringify(list));
|
|
170
|
+
}
|
|
156
171
|
};
|
|
157
172
|
|
|
158
173
|
drafts.migrateGuest = function () {
|
|
159
174
|
// If any drafts are made while as guest, and user then logs in, assume control of those drafts
|
|
160
175
|
if (canSave('localStorage') && app.user.uid) {
|
|
161
|
-
|
|
162
|
-
|
|
176
|
+
// composer:<uid>:<timestamp>
|
|
177
|
+
const test = /^composer:\d+:\d$/;
|
|
178
|
+
const keys = Object.keys(sessionStorage).filter(function (key) {
|
|
163
179
|
return test.test(key);
|
|
164
180
|
});
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
181
|
+
const migrated = new Set([]);
|
|
182
|
+
const renamed = keys.map(function (key) {
|
|
183
|
+
const parts = key.split(':');
|
|
168
184
|
parts[1] = app.user.uid;
|
|
169
185
|
|
|
170
|
-
migrated.add(parts.
|
|
186
|
+
migrated.add(parts.join(':'));
|
|
171
187
|
return parts.join(':');
|
|
172
188
|
});
|
|
173
189
|
|
|
@@ -177,7 +193,7 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
|
|
|
177
193
|
});
|
|
178
194
|
|
|
179
195
|
migrated.forEach(function (save_id) {
|
|
180
|
-
drafts.
|
|
196
|
+
drafts.addToDraftList('available', save_id);
|
|
181
197
|
});
|
|
182
198
|
|
|
183
199
|
return migrated;
|
|
@@ -205,14 +221,8 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
|
|
|
205
221
|
};
|
|
206
222
|
|
|
207
223
|
drafts.listAvailable = function () {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
available = JSON.parse(available) || [];
|
|
211
|
-
return available.map(drafts.get);
|
|
212
|
-
} catch (e) {
|
|
213
|
-
console.warn('[composer/drafts] Could not read list of available drafts');
|
|
214
|
-
}
|
|
215
|
-
return [];
|
|
224
|
+
const available = drafts.getList('available');
|
|
225
|
+
return available.map(drafts.get);
|
|
216
226
|
};
|
|
217
227
|
|
|
218
228
|
drafts.getAvailableCount = function () {
|
|
@@ -228,40 +238,23 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
|
|
|
228
238
|
};
|
|
229
239
|
|
|
230
240
|
drafts.loadOpen = function () {
|
|
231
|
-
if (ajaxify.data.template.login || ajaxify.data.template.register) {
|
|
241
|
+
if (ajaxify.data.template.login || ajaxify.data.template.register || !config.hasOwnProperty('openDraftsOnPageLoad') || !config.openDraftsOnPageLoad) {
|
|
232
242
|
return;
|
|
233
243
|
}
|
|
234
244
|
// Load drafts if they were open
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
try {
|
|
238
|
-
available = localStorage.getItem('drafts:available');
|
|
239
|
-
open = localStorage.getItem('drafts:open');
|
|
240
|
-
available = JSON.parse(available) || [];
|
|
241
|
-
open = JSON.parse(open) || [];
|
|
242
|
-
} catch (e) {
|
|
243
|
-
console.warn('[composer/drafts] Could not read list of open/available drafts');
|
|
244
|
-
available = [];
|
|
245
|
-
open = [];
|
|
246
|
-
}
|
|
245
|
+
const available = drafts.getList('available');
|
|
246
|
+
const open = drafts.getList('open');
|
|
247
247
|
|
|
248
248
|
if (available.length) {
|
|
249
249
|
// Deconstruct each save_id and open up composer
|
|
250
250
|
available.forEach(function (save_id) {
|
|
251
|
-
if (!save_id) {
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
var draft = drafts.get(save_id);
|
|
255
|
-
|
|
256
|
-
// If draft is already open, do nothing
|
|
257
|
-
if (open.indexOf(save_id) !== -1) {
|
|
251
|
+
if (!save_id || open.includes(save_id)) {
|
|
258
252
|
return;
|
|
259
253
|
}
|
|
260
|
-
|
|
254
|
+
const draft = drafts.get(save_id);
|
|
261
255
|
if (!draft || (!draft.text && !draft.title)) {
|
|
262
|
-
|
|
263
|
-
drafts.
|
|
264
|
-
drafts.updateVisibility('open', save_id);
|
|
256
|
+
drafts.removeFromDraftList('available', save_id);
|
|
257
|
+
drafts.removeFromDraftList('open', save_id);
|
|
265
258
|
return;
|
|
266
259
|
}
|
|
267
260
|
openComposer(save_id, draft);
|
|
@@ -270,32 +263,42 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
|
|
|
270
263
|
};
|
|
271
264
|
|
|
272
265
|
function openComposer(save_id, draft) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
var type = saveObj[2];
|
|
276
|
-
var id = saveObj[3];
|
|
266
|
+
const saveObj = save_id.split(':');
|
|
267
|
+
const uid = saveObj[1];
|
|
277
268
|
// Don't open other peoples' drafts
|
|
278
269
|
if (parseInt(app.user.uid, 10) !== parseInt(uid, 10)) {
|
|
279
270
|
return;
|
|
280
271
|
}
|
|
281
272
|
require(['composer'], function (composer) {
|
|
282
|
-
if (
|
|
273
|
+
if (draft.action === 'topics.post') {
|
|
283
274
|
composer.newTopic({
|
|
284
|
-
|
|
275
|
+
save_id: draft.save_id,
|
|
276
|
+
cid: draft.cid,
|
|
285
277
|
handle: app.user && app.user.uid ? undefined : utils.escapeHTML(draft.handle),
|
|
286
278
|
title: utils.escapeHTML(draft.title),
|
|
287
279
|
body: utils.escapeHTML(draft.text),
|
|
288
280
|
tags: String(draft.tags || '').split(','),
|
|
289
281
|
});
|
|
290
|
-
} else if (
|
|
291
|
-
api.get('/topics/' +
|
|
282
|
+
} else if (draft.action === 'posts.reply') {
|
|
283
|
+
api.get('/topics/' + draft.tid, {}, function (err, topicObj) {
|
|
292
284
|
if (err) {
|
|
293
285
|
return alerts.error(err);
|
|
294
286
|
}
|
|
295
|
-
|
|
287
|
+
|
|
288
|
+
composer.newReply({
|
|
289
|
+
save_id: draft.save_id,
|
|
290
|
+
tid: draft.tid,
|
|
291
|
+
toPid: draft.toPid,
|
|
292
|
+
title: topicObj.title,
|
|
293
|
+
body: utils.escapeHTML(draft.text),
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
} else if (draft.action === 'posts.edit') {
|
|
297
|
+
composer.editPost({
|
|
298
|
+
save_id: draft.save_id,
|
|
299
|
+
pid: draft.pid,
|
|
300
|
+
body: utils.escapeHTML(draft.text),
|
|
296
301
|
});
|
|
297
|
-
} else if (type === 'pid') {
|
|
298
|
-
composer.editPost(id);
|
|
299
302
|
}
|
|
300
303
|
});
|
|
301
304
|
}
|
package/static/lib/composer.js
CHANGED
|
@@ -152,15 +152,6 @@ define('composer', [
|
|
|
152
152
|
});
|
|
153
153
|
});
|
|
154
154
|
|
|
155
|
-
// Construct a save_id
|
|
156
|
-
if (post.hasOwnProperty('cid')) {
|
|
157
|
-
post.save_id = ['composer', app.user.uid, 'cid', post.cid].join(':');
|
|
158
|
-
} else if (post.hasOwnProperty('tid')) {
|
|
159
|
-
post.save_id = ['composer', app.user.uid, 'tid', post.tid].join(':');
|
|
160
|
-
} else if (post.hasOwnProperty('pid')) {
|
|
161
|
-
post.save_id = ['composer', app.user.uid, 'pid', post.pid].join(':');
|
|
162
|
-
}
|
|
163
|
-
|
|
164
155
|
composer.posts[uuid] = post;
|
|
165
156
|
composer.load(uuid);
|
|
166
157
|
}
|
|
@@ -197,7 +188,8 @@ define('composer', [
|
|
|
197
188
|
};
|
|
198
189
|
|
|
199
190
|
composer.newTopic = async (data) => {
|
|
200
|
-
|
|
191
|
+
let pushData = {
|
|
192
|
+
save_id: data.save_id,
|
|
201
193
|
action: 'topics.post',
|
|
202
194
|
cid: data.cid,
|
|
203
195
|
handle: data.handle,
|
|
@@ -216,72 +208,90 @@ define('composer', [
|
|
|
216
208
|
push(pushData);
|
|
217
209
|
};
|
|
218
210
|
|
|
219
|
-
composer.addQuote = function (
|
|
220
|
-
|
|
211
|
+
composer.addQuote = function (data) {
|
|
212
|
+
// tid, toPid, selectedPid, title, username, text, uuid
|
|
213
|
+
data.uuid = data.uuid || composer.active;
|
|
221
214
|
|
|
222
|
-
var escapedTitle = (title || '')
|
|
215
|
+
var escapedTitle = (data.title || '')
|
|
223
216
|
.replace(/([\\`*_{}[\]()#+\-.!])/g, '\\$1')
|
|
224
217
|
.replace(/\[/g, '[')
|
|
225
218
|
.replace(/\]/g, ']')
|
|
226
219
|
.replace(/%/g, '%')
|
|
227
220
|
.replace(/,/g, ',');
|
|
228
221
|
|
|
229
|
-
if (
|
|
230
|
-
|
|
222
|
+
if (data.body) {
|
|
223
|
+
data.body = '> ' + data.body.replace(/\n/g, '\n> ') + '\n\n';
|
|
231
224
|
}
|
|
232
|
-
var link = '[' + escapedTitle + '](' + config.relative_path + '/post/' + (selectedPid || toPid) + ')';
|
|
233
|
-
if (uuid === undefined) {
|
|
234
|
-
if (title && (selectedPid || toPid)) {
|
|
235
|
-
composer.newReply(
|
|
225
|
+
var link = '[' + escapedTitle + '](' + config.relative_path + '/post/' + (data.selectedPid || data.toPid) + ')';
|
|
226
|
+
if (data.uuid === undefined) {
|
|
227
|
+
if (data.title && (data.selectedPid || data.toPid)) {
|
|
228
|
+
composer.newReply({
|
|
229
|
+
tid: data.tid,
|
|
230
|
+
toPid: data.toPid,
|
|
231
|
+
title: data.title,
|
|
232
|
+
body: '[[modules:composer.user_said_in, ' + data.username + ', ' + link + ']]\n' + data.body,
|
|
233
|
+
});
|
|
236
234
|
} else {
|
|
237
|
-
composer.newReply(
|
|
235
|
+
composer.newReply({
|
|
236
|
+
tid: data.tid,
|
|
237
|
+
toPid: data.toPid,
|
|
238
|
+
title: data.title,
|
|
239
|
+
body: '[[modules:composer.user_said, ' + data.username + ']]\n' + data.body,
|
|
240
|
+
});
|
|
238
241
|
}
|
|
239
242
|
return;
|
|
240
|
-
} else if (uuid !== composer.active) {
|
|
243
|
+
} else if (data.uuid !== composer.active) {
|
|
241
244
|
// If the composer is not currently active, activate it
|
|
242
|
-
composer.load(uuid);
|
|
245
|
+
composer.load(data.uuid);
|
|
243
246
|
}
|
|
244
247
|
|
|
245
|
-
var postContainer = $('.composer[data-uuid="' + uuid + '"]');
|
|
248
|
+
var postContainer = $('.composer[data-uuid="' + data.uuid + '"]');
|
|
246
249
|
var bodyEl = postContainer.find('textarea');
|
|
247
250
|
var prevText = bodyEl.val();
|
|
248
|
-
if (title && (selectedPid || toPid)) {
|
|
249
|
-
translator.translate('[[modules:composer.user_said_in, ' + username + ', ' + link + ']]\n', config.defaultLang, onTranslated);
|
|
251
|
+
if (data.title && (data.selectedPid || data.toPid)) {
|
|
252
|
+
translator.translate('[[modules:composer.user_said_in, ' + data.username + ', ' + link + ']]\n', config.defaultLang, onTranslated);
|
|
250
253
|
} else {
|
|
251
|
-
translator.translate('[[modules:composer.user_said, ' + username + ']]\n', config.defaultLang, onTranslated);
|
|
254
|
+
translator.translate('[[modules:composer.user_said, ' + data.username + ']]\n', config.defaultLang, onTranslated);
|
|
252
255
|
}
|
|
253
256
|
|
|
254
257
|
function onTranslated(translated) {
|
|
255
|
-
composer.posts[uuid].body = (prevText.length ? prevText + '\n\n' : '') + translated +
|
|
256
|
-
bodyEl.val(composer.posts[uuid].body);
|
|
258
|
+
composer.posts[data.uuid].body = (prevText.length ? prevText + '\n\n' : '') + translated + data.body;
|
|
259
|
+
bodyEl.val(composer.posts[data.uuid].body);
|
|
257
260
|
focusElements(postContainer);
|
|
258
261
|
preview.render(postContainer);
|
|
259
262
|
}
|
|
260
263
|
};
|
|
261
264
|
|
|
262
|
-
composer.newReply = function (
|
|
263
|
-
translator.translate(
|
|
265
|
+
composer.newReply = function (data) {
|
|
266
|
+
translator.translate(data.body, config.defaultLang, function (translated) {
|
|
264
267
|
push({
|
|
268
|
+
save_id: data.save_id,
|
|
265
269
|
action: 'posts.reply',
|
|
266
|
-
tid: tid,
|
|
267
|
-
toPid: toPid,
|
|
268
|
-
title: title,
|
|
270
|
+
tid: data.tid,
|
|
271
|
+
toPid: data.toPid,
|
|
272
|
+
title: data.title,
|
|
269
273
|
body: translated,
|
|
270
|
-
modified: !!((title && title.length) || (translated && translated.length)),
|
|
274
|
+
modified: !!((data.title && data.title.length) || (translated && translated.length)),
|
|
271
275
|
isMain: false,
|
|
272
276
|
});
|
|
273
277
|
});
|
|
274
278
|
};
|
|
275
279
|
|
|
276
|
-
composer.editPost = function (
|
|
277
|
-
|
|
280
|
+
composer.editPost = function (data) {
|
|
281
|
+
// pid, text
|
|
282
|
+
socket.emit('plugins.composer.push', data.pid, function (err, postData) {
|
|
278
283
|
if (err) {
|
|
279
284
|
return alerts.error(err);
|
|
280
285
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
286
|
+
postData.save_id = data.save_id;
|
|
287
|
+
postData.action = 'posts.edit';
|
|
288
|
+
postData.pid = data.pid;
|
|
289
|
+
postData.modified = false;
|
|
290
|
+
if (data.body) {
|
|
291
|
+
postData.body = data.body;
|
|
292
|
+
postData.modified = true;
|
|
293
|
+
}
|
|
294
|
+
push(postData);
|
|
285
295
|
});
|
|
286
296
|
};
|
|
287
297
|
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
<div class="title-container">
|
|
2
2
|
{{{ if isTopic }}}
|
|
3
|
-
<div class="category-list-container hidden-sm hidden-xs">
|
|
3
|
+
<div class="category-list-container hidden-sm hidden-xs align-self-center">
|
|
4
4
|
<!-- IMPORT partials/category-selector.tpl -->
|
|
5
5
|
</div>
|
|
6
6
|
{{{ end }}}
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
{{{ if showHandleInput }}}
|
|
9
9
|
<div data-component="composer/handle">
|
|
10
10
|
<input class="handle form-control h-100" type="text" tabindex="1" placeholder="[[topic:composer.handle_placeholder]]" value="{handle}" />
|
|
11
11
|
</div>
|
|
12
|
-
|
|
12
|
+
{{{ end }}}
|
|
13
13
|
<div data-component="composer/title" class="position-relative">
|
|
14
|
-
|
|
14
|
+
{{{ if isTopicOrMain }}}
|
|
15
15
|
<input class="title form-control h-100" type="text" tabindex="1" placeholder="[[topic:composer.title_placeholder]]" value="{topicTitle}"/>
|
|
16
|
-
|
|
17
|
-
<span class="title h-100">[[topic:composer.replying_to, "{topicTitle}"]]</span>
|
|
18
|
-
|
|
16
|
+
{{{ else }}}
|
|
17
|
+
<span class="title h-100">{{{ if isEditing }}}[[topic:composer.editing]]{{{ else }}}[[topic:composer.replying_to, "{topicTitle}"]]{{{ end }}}</span>
|
|
18
|
+
{{{ end }}}
|
|
19
19
|
<div id="quick-search-container" class="quick-search-container mt-2 dropdown-menu d-block p-2 hidden">
|
|
20
20
|
<div class="text-center loading-indicator"><i class="fa fa-spinner fa-spin"></i></div>
|
|
21
21
|
<div class="quick-search-results-container"></div>
|