Skip to content

Commit ad06c12

Browse files
authored
Merge branch 'feature/7.8.0/DOC-3131' into feature/7.8.0/DOC-3131_TINY-11748
2 parents 60c1945 + b6f83b4 commit ad06c12

File tree

22 files changed

+764
-1132
lines changed

22 files changed

+764
-1132
lines changed

modules/ROOT/examples/live-demos/comments-callback-with-mentions/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<textarea id="comments-callback">
1+
<textarea id="comments-callback-with-mentions">
22
<h2>Welcome to Tiny Comments!</h2>
33
<p>Please try out this demo of our Tiny Comments premium plugin with @mentions support.</p>
44
<ol>

modules/ROOT/examples/live-demos/comments-callback-with-mentions/index.js

Lines changed: 158 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,73 @@
11
import ('https://cdn.jsdelivr.net/npm/@faker-js/faker@9/dist/index.min.js').then(({ faker }) => {
2-
const adminUser = {
3-
id: 'johnsmith',
4-
name: 'John Smith',
5-
fullName: 'John Smith',
6-
description: 'Company Founder',
7-
image: "https://i.pravatar.cc/150?img=11"
2+
const userDb = {
3+
'michaelcook': {
4+
id: 'michaelcook',
5+
name: 'Michael Cook',
6+
fullName: 'Michael Cook',
7+
description: 'Product Owner',
8+
image: "{{imagesdir}}/avatars/michaelcook.png"
9+
},
10+
'kalebwilson': {
11+
id: 'kalebwilson',
12+
name: 'Kaleb Wilson',
13+
fullName: 'Kaleb Wilson',
14+
description: 'Marketing Director',
15+
image: "{{imagesdir}}/avatars/kalebwilson.png"
16+
}
817
};
9-
10-
const currentUser = {
11-
id: 'jennynichols',
12-
name: 'Jenny Nichols',
13-
fullName: 'Jenny Nichols',
14-
description: 'Marketing Director',
15-
image: "https://i.pravatar.cc/150?img=10"
18+
19+
const currentUid = 'kalebwilson';
20+
const adminUid = 'michaelcook';
21+
22+
const currentUser = userDb[currentUid];
23+
const adminUser = userDb[adminUid];
24+
25+
const now = new Date();
26+
const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000).toISOString();
27+
const anhourago = new Date(now.getTime() - 60 * 60 * 1000).toISOString();
28+
29+
const fillAuthorInfo = (id, fullName, image) => ({
30+
author: id,
31+
authorName: fullName,
32+
authorAvatar: image,
33+
});
34+
35+
const getAuthorInfo = (uid) => {
36+
const user = userDb[uid];
37+
if (user) {
38+
return fillAuthorInfo(user.id, user.fullName, user.image);
39+
}
40+
return {
41+
author: uid,
42+
authorName: uid,
43+
};
1644
};
1745

1846
const conversationDb = {
1947
'mce-conversation_19679600221621399703915': {
2048
uid: 'mce-conversation_19679600221621399703915',
2149
comments: [{
2250
uid: 'mce-conversation_19679600221621399703915',
23-
author: currentUser.id,
24-
authorName: currentUser.fullName,
25-
authorAvatar: currentUser.image,
26-
content: `What do you think about this @${adminUser.id}?`,
27-
createdAt: '2021-05-19T04:48:23.914Z',
28-
modifiedAt: '2021-05-19T04:48:23.914Z'
29-
},
30-
{
51+
...getAuthorInfo(currentUid),
52+
content: `What do you think about this? @${adminUser.id}?`,
53+
createdAt: yesterday,
54+
modifiedAt: yesterday
55+
}, {
3156
uid: 'mce-conversation_19679600221621399703917',
32-
author: adminUser.id,
33-
authorName: adminUser.fullName,
34-
authorAvatar: adminUser.image,
57+
...getAuthorInfo(adminUid),
3558
content: `I think this is a great idea @${currentUser.id}!`,
36-
createdAt: "2024-05-28T12:54:24.126Z",
37-
modifiedAt: "2024-05-28T12:54:24.126Z",
59+
createdAt: anhourago,
60+
modifiedAt: anhourago,
3861
}]
3962
},
4063
'mce-conversation_420304606321716900864126': {
4164
uid: 'mce-conversation_420304606321716900864126',
4265
comments: [{
4366
uid: 'mce-conversation_420304606321716900864126',
44-
author: adminUser.id,
45-
authorName: adminUser.fullName,
46-
authorAvatar: adminUser.image,
67+
...getAuthorInfo(adminUid),
4768
content: `@${currentUser.id} Please revise this sentence, exclamation points are unprofessional!`,
48-
createdAt: '2024-05-28T12:54:24.126Z',
49-
modifiedAt: '2024-05-28T12:54:24.126Z'
69+
createdAt: yesterday,
70+
modifiedAt: anhourago
5071
}]
5172
}
5273
};
@@ -122,6 +143,10 @@ import ('https://cdn.jsdelivr.net/npm/@faker-js/faker@9/dist/index.min.js').then
122143

123144
const fakeServer = setupFakeServer();
124145

146+
/********************************
147+
* Mentions functions *
148+
********************************/
149+
125150
const mentions_fetch = (query, success) => {
126151
if (!fetchedUsers) {
127152
fetchedUsers = true;
@@ -162,6 +187,11 @@ import ('https://cdn.jsdelivr.net/npm/@faker-js/faker@9/dist/index.min.js').then
162187
}
163188
};
164189

190+
/********************************
191+
* Tiny Comments functions *
192+
* (must call "done" or "fail") *
193+
********************************/
194+
165195
const tinycomments_create = (req, done, fail) => {
166196
if (req.content === 'fail') {
167197
fail(new Error('Something has gone wrong...'));
@@ -170,131 +200,132 @@ import ('https://cdn.jsdelivr.net/npm/@faker-js/faker@9/dist/index.min.js').then
170200
conversationDb[uid] = {
171201
uid,
172202
comments: [{
173-
uid,
174-
authorName: currentUser.fullName,
175-
authorAvatar: currentUser.image,
176-
author: currentUser.name,
177-
content: req.content,
178-
createdAt: req.createdAt,
179-
modifiedAt: req.createdAt
203+
uid,
204+
...getAuthorInfo(currentUid),
205+
content: req.content,
206+
createdAt: req.createdAt,
207+
modifiedAt: req.createdAt
180208
}]
181209
};
182-
183-
setTimeout(() => {
184-
done({
185-
conversationUid: uid
186-
});
187-
}, fakeDelay);
210+
setTimeout(() => done({ conversationUid: uid }), fakeDelay);
188211
}
189212
};
190-
213+
191214
const tinycomments_reply = (req, done) => {
192215
const replyUid = 'annotation-' + randomString();
193-
const current = conversationDb[req.conversationUid];
194-
current.comments.push(
195-
{
196-
uid: replyUid,
197-
authorName: currentUser.fullName,
198-
authorAvatar: currentUser.image,
199-
author: currentUser.name,
200-
content: req.content,
201-
createdAt: req.createdAt,
202-
modifiedAt: req.createdAt
203-
}
204-
);
205-
206-
setTimeout(() => {
207-
done({
208-
commentUid: replyUid
209-
});
210-
}, fakeDelay);
216+
conversationDb[req.conversationUid].comments.push({
217+
uid: replyUid,
218+
...getAuthorInfo(currentUid),
219+
content: req.content,
220+
createdAt: req.createdAt,
221+
modifiedAt: req.createdAt
222+
});
223+
setTimeout(() => done({ commentUid: replyUid }), fakeDelay);
211224
};
212-
225+
213226
const tinycomments_delete = (req, done) => {
214-
delete conversationDb[req.conversationUid];
215-
216-
setTimeout(() => {
217-
done({
218-
canDelete: true
219-
});
220-
}, fakeDelay);
227+
if (currentUid === adminUid) { // Replace wth your own logic, e.g. check if user created the conversation
228+
delete conversationDb[req.conversationUid];
229+
setTimeout(() => done({ canDelete: true }), fakeDelay);
230+
} else {
231+
setTimeout(() => done({ canDelete: false, reason: 'Must be admin user' }), fakeDelay);
232+
}
221233
};
222-
234+
223235
const tinycomments_resolve = (req, done) => {
224-
resolvedConversationDb[req.conversationUid] = conversationDb[req.conversationUid];
225-
delete conversationDb[req.conversationUid];
226-
227-
setTimeout(() => {
228-
done({
229-
canResolve: true
230-
});
231-
}, fakeDelay);
236+
const conversation = conversationDb[req.conversationUid];
237+
if (currentUid === conversation.comments[0].author) { // Replace wth your own logic, e.g. check if user has admin priveleges
238+
delete conversationDb[req.conversationUid];
239+
setTimeout(() => done({ canResolve: true }), fakeDelay);
240+
} else {
241+
setTimeout(() => done({ canResolve: false, reason: 'Must be conversation author' }), fakeDelay);
242+
}
232243
};
233-
244+
234245
const tinycomments_delete_comment = (req, done) => {
235-
const current = conversationDb[req.conversationUid];
236-
// Should be supported on browsers ...
237-
current.comments = current.comments.filter((f) => {
238-
return f.uid !== req.commentUid;
246+
const oldcomments = conversationDb[req.conversationUid].comments;
247+
let reason = 'Comment not found';
248+
249+
const newcomments = oldcomments.filter((comment) => {
250+
if (comment.uid === req.commentUid) { // Found the comment to delete
251+
if (currentUid === comment.author) { // Replace with your own logic, e.g. check if user has admin privileges
252+
return false; // Remove the comment
253+
} else {
254+
reason = 'Not authorised to delete this comment'; // Update reason
255+
}
256+
}
257+
return true; // Keep the comment
239258
});
240-
241-
setTimeout(() => {
242-
done({
243-
canDelete: true
244-
});
245-
}, fakeDelay);
259+
if (newcomments.length === oldcomments.length) {
260+
setTimeout(() => done({ canDelete: false, reason }), fakeDelay);
261+
} else {
262+
conversationDb[req.conversationUid].comments = newcomments;
263+
setTimeout(() => done({ canDelete: true }), fakeDelay);
264+
}
246265
};
247-
266+
248267
const tinycomments_edit_comment = (req, done) => {
249-
const current = conversationDb[req.conversationUid];
250-
// Should be supported on browsers ...
251-
current.comments = current.comments.map((f) => {
252-
return f.uid === req.commentUid ? {
253-
...f,
254-
content: req.content,
255-
modifiedAt: new Date().toISOString()
256-
} : f;
268+
const oldcomments = conversationDb[req.conversationUid].comments;
269+
let reason = 'Comment not found';
270+
let canEdit = false;
271+
272+
const newcomments = oldcomments.map((comment) => {
273+
if (comment.uid === req.commentUid) { // Found the comment to delete
274+
if (currentUid === comment.author) { // Replace with your own logic, e.g. check if user has admin privileges
275+
canEdit = true; // User can edit the comment
276+
return { ...comment, content: req.content, modifiedAt: new Date().toISOString() }; // Update the comment
277+
} else {
278+
reason = 'Not authorised to edit this comment'; // Update reason
279+
}
280+
}
281+
return comment; // Keep the comment
257282
});
258-
259-
setTimeout(() => {
260-
done({
261-
canEdit: true
262-
});
263-
}, fakeDelay);
283+
284+
if (canEdit) {
285+
conversationDb[req.conversationUid].comments = newcomments;
286+
setTimeout(() => done({ canEdit }), fakeDelay);
287+
} else {
288+
setTimeout(() => done({ canEdit, reason }), fakeDelay);
289+
}
264290
};
265-
291+
266292
const tinycomments_delete_all = (req, done) => {
267-
Object.keys(conversationDb).forEach((k) => {
268-
delete conversationDb[k];
269-
});
270-
271-
setTimeout(() => {
272-
done({
273-
canDelete: true
274-
});
275-
}, fakeDelay);
293+
const conversation = conversationDb[req.conversationUid];
294+
if (currentUid === conversation.comments[0].author) { // Replace wth your own logic, e.g. check if user has admin priveleges
295+
delete conversationDb[req.conversationUid];
296+
setTimeout(() => done({ canDelete: true }), fakeDelay);
297+
} else {
298+
setTimeout(() => done({ canDelete: false, reason: 'Must be conversation author' }), fakeDelay);
299+
}
276300
};
277-
301+
278302
const tinycomments_lookup = (req, done) => {
279303
setTimeout(() => {
280304
done({
281305
conversation: {
282-
uid: conversationDb[req.conversationUid].uid,
283-
comments: conversationDb[req.conversationUid].comments.slice(0)
306+
uid: conversationDb[req.conversationUid].uid,
307+
comments: [...conversationDb[req.conversationUid].comments]
284308
}
285309
});
286310
}, fakeDelay);
287311
};
288-
289-
const tinycomments_fetch = (_, done) => {
290-
setTimeout(() => done({
291-
conversations: conversationDb
292-
}), fakeDelay);
312+
313+
const tinycomments_fetch = (conversationUids, done) => {
314+
const fetchedConversations = {};
315+
conversationUids.forEach((uid) => {
316+
const conversation = conversationDb[uid];
317+
if (conversation) {
318+
fetchedConversations[uid] = {...conversation};
319+
}
320+
});
321+
setTimeout(() => done({ conversations: fetchedConversations }), fakeDelay);
293322
};
294-
323+
324+
// Read the above `getAuthorInfo` function to see how this could be implemented
325+
const tinycomments_fetch_author_info = (done) => done(getAuthorInfo(currentUid));
295326

296327
tinymce.init({
297-
selector: 'textarea#comments-callback',
328+
selector: 'textarea#comments-callback-with-mentions',
298329
license_key: 'gpl',
299330
toolbar: 'addcomment showcomments code | bold italic underline',
300331
menubar: 'file edit view insert format tools tc help',
@@ -331,5 +362,6 @@ import ('https://cdn.jsdelivr.net/npm/@faker-js/faker@9/dist/index.min.js').then
331362
tinycomments_delete_comment,
332363
tinycomments_edit_comment,
333364
tinycomments_fetch,
365+
tinycomments_fetch_author_info
334366
});
335367
});

0 commit comments

Comments
 (0)