11/********************************
2- * Tiny Comments functions *
3- * (must call "done" or "fail") *
2+ * Demo-specific configuration *
43 ********************************/
54
6- import ( 'https://cdn.jsdelivr.net/npm/@faker-js/faker@9/dist/index.min.js' ) . then ( ( ) => {
7- const adminUser = {
8- id : 'johnsmith' ,
9- name : 'John Smith' ,
10- fullName : 'John Smith' ,
11- description : 'Company Founder' ,
12- image : "https://i.pravatar.cc/150?img=11"
13- } ;
14-
15- const currentUser = {
16- id : 'Bennichols' ,
17- name : 'Ben Nichols' ,
18- fullName : 'Ben Nichols' ,
5+ const userDb = {
6+ 'michaelcook' : {
7+ id : 'michaelcook' ,
8+ name : 'Michael Cook' ,
9+ fullName : 'Michael Cook' ,
10+ description : 'Product Owner' ,
11+ image : "{{imagesdir}}/avatars/michaelcook.png"
12+ } ,
13+ 'kalebwilson' : {
14+ id : 'kalebwilson' ,
15+ name : 'Kaleb Wilson' ,
16+ fullName : 'Kaleb Wilson' ,
1917 description : 'Marketing Director' ,
20- image :
"https://fiddle.tiny.cloud/images/[email protected] " 18+ image : "{{imagesdir}}/avatars/kalebwilson.png"
19+ }
20+ } ;
21+
22+ const currentUid = 'kalebwilson' ;
23+ const adminUid = 'michaelcook' ;
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 ,
2143 } ;
44+ }
2245
23- const conversationDb = {
24- 'mce-conversation_19679600221621399703915' : {
46+ const conversationDb = {
47+ 'mce-conversation_19679600221621399703915' : {
48+ uid : 'mce-conversation_19679600221621399703915' ,
49+ comments : [ {
2550 uid : 'mce-conversation_19679600221621399703915' ,
26- comments : [ {
27- uid : 'mce-conversation_19679600221621399703915' ,
28- author : currentUser . id ,
29- authorName : currentUser . fullName ,
30- authorAvatar : currentUser . image ,
31- content : `What do you think about this?` ,
32- createdAt : '2021-05-19T04:48:23.914Z' ,
33- modifiedAt : '2021-05-19T04:48:23.914Z'
34- } , {
35- uid : 'mce-conversation_19679600221621399703917' ,
36- author : adminUser . id ,
37- authorName : adminUser . fullName ,
38- authorAvatar : adminUser . image ,
39- content : `I think this is a great idea!` ,
40- createdAt : "2024-05-28T12:54:24.126Z" ,
41- modifiedAt : "2024-05-28T12:54:24.126Z" ,
42- } ]
43- } ,
44- 'mce-conversation_420304606321716900864126' : {
51+ ...getAuthorInfo ( currentUid ) ,
52+ content : `What do you think about this?` ,
53+ createdAt : yesterday ,
54+ modifiedAt : yesterday
55+ } , {
56+ uid : 'mce-conversation_19679600221621399703917' ,
57+ ...getAuthorInfo ( adminUid ) ,
58+ content : `I think this is a great idea!` ,
59+ createdAt : anhourago ,
60+ modifiedAt : anhourago ,
61+ } ]
62+ } ,
63+ 'mce-conversation_420304606321716900864126' : {
64+ uid : 'mce-conversation_420304606321716900864126' ,
65+ comments : [ {
4566 uid : 'mce-conversation_420304606321716900864126' ,
46- comments : [ {
47- uid : 'mce-conversation_420304606321716900864126' ,
48- author : adminUser . id ,
49- authorName : adminUser . fullName ,
50- authorAvatar : adminUser . image ,
51- content : `Please revise this sentence, exclamation points are unprofessional!` ,
52- createdAt : '2024-05-28T12:54:24.126Z' ,
53- modifiedAt : '2024-05-28T12:54:24.126Z'
54- } ]
55- }
56- } ;
67+ ...getAuthorInfo ( adminUid ) ,
68+ content : `Please revise this sentence, exclamation points are unprofessional!` ,
69+ createdAt : yesterday ,
70+ modifiedAt : anhourago
71+ } ]
72+ }
73+ } ;
74+
75+ const fakeDelay = 200 ;
76+ const randomString = ( ) => crypto . getRandomValues ( new Uint32Array ( 1 ) ) [ 0 ] . toString ( 36 ) . substring ( 2 , 14 ) ;
5777
58- const fakeDelay = 200 ;
59- const randomString = ( ) => crypto . getRandomValues ( new Uint32Array ( 1 ) ) [ 0 ] . toString ( 36 ) . substring ( 2 , 14 ) ;
78+ const resolvedConversationDb = { } ;
6079
61- const resolvedConversationDb = { } ;
80+ /********************************
81+ * Tiny Comments functions *
82+ * (must call "done" or "fail") *
83+ ********************************/
6284
63- const tinycomments_create = ( req , done , fail ) => {
64- if ( req . content === 'fail' ) {
65- fail ( new Error ( 'Something has gone wrong...' ) ) ;
66- } else {
67- const uid = 'annotation-' + randomString ( ) ;
68- conversationDb [ uid ] = {
85+ const tinycomments_create = ( req , done , fail ) => {
86+ if ( req . content === 'fail' ) {
87+ fail ( new Error ( 'Something has gone wrong...' ) ) ;
88+ } else {
89+ const uid = 'annotation-' + randomString ( ) ;
90+ conversationDb [ uid ] = {
91+ uid,
92+ comments : [ {
6993 uid,
70- comments : [ {
71- uid,
72- authorName : currentUser . fullName ,
73- authorAvatar : currentUser . image ,
74- author : currentUser . name ,
75- content : req . content ,
76- createdAt : req . createdAt ,
77- modifiedAt : req . createdAt
78- } ]
79- } ;
80- setTimeout ( ( ) => done ( { conversationUid : uid } ) , fakeDelay ) ;
81- }
82- } ;
94+ ...getAuthorInfo ( currentUid ) ,
95+ content : req . content ,
96+ createdAt : req . createdAt ,
97+ modifiedAt : req . createdAt
98+ } ]
99+ } ;
100+ setTimeout ( ( ) => done ( { conversationUid : uid } ) , fakeDelay ) ;
101+ }
102+ } ;
83103
84- const tinycomments_reply = ( req , done ) => {
85- const replyUid = 'annotation-' + randomString ( ) ;
86- conversationDb [ req . conversationUid ] . comments . push ( {
87- uid : replyUid ,
88- authorName : currentUser . fullName ,
89- authorAvatar : currentUser . image ,
90- author : currentUser . name ,
91- content : req . content ,
92- createdAt : req . createdAt ,
93- modifiedAt : req . createdAt
94- } ) ;
95- setTimeout ( ( ) => done ( { commentUid : replyUid } ) , fakeDelay ) ;
96- } ;
104+ const tinycomments_reply = ( req , done ) => {
105+ const replyUid = 'annotation-' + randomString ( ) ;
106+ conversationDb [ req . conversationUid ] . comments . push ( {
107+ uid : replyUid ,
108+ ...getAuthorInfo ( currentUid ) ,
109+ content : req . content ,
110+ createdAt : req . createdAt ,
111+ modifiedAt : req . createdAt
112+ } ) ;
113+ setTimeout ( ( ) => done ( { commentUid : replyUid } ) , fakeDelay ) ;
114+ } ;
97115
98- const tinycomments_delete = ( req , done ) => {
116+ const tinycomments_delete = ( req , done ) => {
117+ if ( currentUid === adminUid ) { // Replace wth your own logic, e.g. check if user created the conversation
99118 delete conversationDb [ req . conversationUid ] ;
100119 setTimeout ( ( ) => done ( { canDelete : true } ) , fakeDelay ) ;
101- } ;
120+ } else {
121+ setTimeout ( ( ) => done ( { canDelete : false , reason : 'Must be admin user' } ) , fakeDelay ) ;
122+ }
123+ } ;
102124
103- const tinycomments_resolve = ( req , done ) => {
104- resolvedConversationDb [ req . conversationUid ] = conversationDb [ req . conversationUid ] ;
125+ const tinycomments_resolve = ( req , done ) => {
126+ const conversation = conversationDb [ req . conversationUid ] ;
127+ if ( currentUid === conversation . comments [ 0 ] . author ) { // Replace wth your own logic, e.g. check if user has admin priveleges
105128 delete conversationDb [ req . conversationUid ] ;
106129 setTimeout ( ( ) => done ( { canResolve : true } ) , fakeDelay ) ;
107- } ;
108-
109- const tinycomments_delete_comment = ( req , done ) => {
110- conversationDb [ req . conversationUid ] . comments = conversationDb [ req . conversationUid ] . comments . filter (
111- ( f ) => f . uid !== req . commentUid
112- ) ;
113- setTimeout ( ( ) => done ( { canDelete : true } ) , fakeDelay ) ;
114- } ;
130+ } else {
131+ setTimeout ( ( ) => done ( { canResolve : false , reason : 'Must be conversation author' } ) , fakeDelay ) ;
132+ }
133+ } ;
115134
116- const tinycomments_edit_comment = ( req , done ) => {
117- conversationDb [ req . conversationUid ] . comments = conversationDb [ req . conversationUid ] . comments . map (
118- ( f ) => f . uid === req . commentUid ? { ...f , content : req . content , modifiedAt : new Date ( ) . toISOString ( ) } : f
119- ) ;
120- setTimeout ( ( ) => done ( { canEdit : true } ) , fakeDelay ) ;
121- } ;
135+ const tinycomments_delete_comment = ( req , done ) => {
136+ const oldcomments = conversationDb [ req . conversationUid ] . comments ;
137+ let reason = 'Comment not found' ;
122138
123- const tinycomments_delete_all = ( _ , done ) => {
124- Object . keys ( conversationDb ) . forEach ( ( k ) => delete conversationDb [ k ] ) ;
139+ const newcomments = oldcomments . filter ( ( comment ) => {
140+ if ( comment . uid === req . commentUid ) { // Found the comment to delete
141+ if ( currentUid === comment . author ) { // Replace with your own logic, e.g. check if user has admin privileges
142+ return false ; // Remove the comment
143+ } else {
144+ reason = 'Not authorised to delete this comment' ; // Update reason
145+ }
146+ }
147+ return true ; // Keep the comment
148+ } ) ;
149+ if ( newcomments . length === oldcomments . length ) {
150+ setTimeout ( ( ) => done ( { canDelete : false , reason } ) , fakeDelay ) ;
151+ } else {
152+ conversationDb [ req . conversationUid ] . comments = newcomments ;
125153 setTimeout ( ( ) => done ( { canDelete : true } ) , fakeDelay ) ;
126- } ;
154+ }
155+ } ;
127156
128- const tinycomments_lookup = ( req , done ) => {
129- setTimeout ( ( ) => {
130- done ( {
131- conversation : {
132- uid : conversationDb [ req . conversationUid ] . uid ,
133- comments : [ ...conversationDb [ req . conversationUid ] . comments ]
134- }
135- } ) ;
136- } , fakeDelay ) ;
137- } ;
157+ const tinycomments_edit_comment = ( req , done ) => {
158+ const oldcomments = conversationDb [ req . conversationUid ] . comments ;
159+ let reason = 'Comment not found' ;
160+ let canEdit = false ;
138161
139- tinymce . init ( {
140- selector : 'textarea#comments-callback' ,
141- license_key : 'gpl' ,
142- height : 800 ,
143- toolbar : 'addcomment showcomments code | bold italic underline' ,
144- menubar : 'file edit view insert format tools tc help' ,
145- menu : {
146- tc : {
147- title : 'TinyComments' ,
148- items : 'addcomment showcomments deleteallconversations'
162+ const newcomments = oldcomments . map ( ( comment ) => {
163+ if ( comment . uid === req . commentUid ) { // Found the comment to delete
164+ if ( currentUid === comment . author ) { // Replace with your own logic, e.g. check if user has admin privileges
165+ canEdit = true ; // User can edit the comment
166+ return { ...comment , content : req . content , modifiedAt : new Date ( ) . toISOString ( ) } ; // Update the comment
167+ } else {
168+ reason = 'Not authorised to edit this comment' ; // Update reason
149169 }
150- } ,
151- plugins : [ 'tinycomments' , 'help' , 'code' , 'quickbars' , 'link' , 'lists' , 'image' ] ,
152- quickbars_selection_toolbar : 'alignleft aligncenter alignright | addcomment showcomments' ,
153- quickbars_image_toolbar : 'alignleft aligncenter alignright | rotateleft rotateright | imageoptions' ,
154- sidebar_show : 'showcomments' ,
155- tinycomments_mode : 'callback' ,
156- tinycomments_author : currentUser . id ,
157- tinycomments_author_name : currentUser . fullName ,
158- tinycomments_avatar : currentUser . image ,
159- tinycomments_create,
160- tinycomments_reply,
161- tinycomments_delete,
162- tinycomments_resolve,
163- tinycomments_delete_all,
164- tinycomments_lookup,
165- tinycomments_delete_comment,
166- tinycomments_edit_comment,
170+ }
171+ return comment ; // Keep the comment
167172 } ) ;
173+
174+ if ( canEdit ) {
175+ conversationDb [ req . conversationUid ] . comments = newcomments ;
176+ setTimeout ( ( ) => done ( { canEdit } ) , fakeDelay ) ;
177+ } else {
178+ setTimeout ( ( ) => done ( { canEdit, reason } ) , fakeDelay ) ;
179+ }
180+ } ;
181+
182+ const tinycomments_delete_all = ( req , done ) => {
183+ const conversation = conversationDb [ req . conversationUid ] ;
184+ if ( currentUid === conversation . comments [ 0 ] . author ) { // Replace wth your own logic, e.g. check if user has admin priveleges
185+ delete conversationDb [ req . conversationUid ] ;
186+ setTimeout ( ( ) => done ( { canDelete : true } ) , fakeDelay ) ;
187+ } else {
188+ setTimeout ( ( ) => done ( { canDelete : false , reason : 'Must be conversation author' } ) , fakeDelay ) ;
189+ }
190+ } ;
191+
192+ const tinycomments_lookup = ( req , done ) => {
193+ setTimeout ( ( ) => {
194+ done ( {
195+ conversation : {
196+ uid : conversationDb [ req . conversationUid ] . uid ,
197+ comments : [ ...conversationDb [ req . conversationUid ] . comments ]
198+ }
199+ } ) ;
200+ } , fakeDelay ) ;
201+ } ;
202+
203+ tinymce . init ( {
204+ selector : 'textarea#comments-callback' ,
205+ license_key : 'gpl' ,
206+ height : 800 ,
207+ toolbar : 'addcomment showcomments code | bold italic underline' ,
208+ menubar : 'file edit view insert format tools tc help' ,
209+ menu : {
210+ tc : {
211+ title : 'TinyComments' ,
212+ items : 'addcomment showcomments deleteallconversations'
213+ }
214+ } ,
215+ plugins : [ 'tinycomments' , 'help' , 'code' , 'quickbars' , 'link' , 'lists' , 'image' ] ,
216+ quickbars_selection_toolbar : 'alignleft aligncenter alignright | addcomment showcomments' ,
217+ quickbars_image_toolbar : 'alignleft aligncenter alignright | rotateleft rotateright | imageoptions' ,
218+ sidebar_show : 'showcomments' ,
219+ tinycomments_mode : 'callback' ,
220+ tinycomments_create,
221+ tinycomments_reply,
222+ tinycomments_delete,
223+ tinycomments_resolve,
224+ tinycomments_delete_all,
225+ tinycomments_lookup,
226+ tinycomments_delete_comment,
227+ tinycomments_edit_comment,
168228} ) ;
0 commit comments