diff --git a/locallib.php b/locallib.php
index 8210ee36f68244e5c55b1ae203719762fb74de03..71d344bf8be13a6bb14ac3059516b36e64d9589b 100644
--- a/locallib.php
+++ b/locallib.php
@@ -64,7 +64,7 @@ function pdfannotator_display_embed($pdfannotator, $cm, $course, $file, $page =
     // Load and execute the javascript files.
     $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/pdf.js?ver=00002"));
     $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/textclipper.js"));
-    $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/index.js?ver=00032"));
+    $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/index.js?ver=00033"));
     $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/locallib.js?ver=00005"));
 
     // Pass parameters from PHP to JavaScript.
@@ -368,233 +368,6 @@ function pdfannotator_file_prepare_draft_area(&$draftitemid, $contextid, $compon
     return file_rewrite_pluginfile_urls($text, 'draftfile.php', $usercontext->id, 'user', 'draft', $draftitemid, $options);
 }
 
-/**
- * Just like the file_save_draft_area_files core function.
- * However, we need to store fileid and commentid in pdfannotator_embeddedfiles
- * and add its id into the html code from the corresponding files.
- * @return string|null if $text was passed in, the rewritten $text is returned. 
- * Otherwise NULL.
- */
-function pdfannotator_file_save_draft_area_files($draftitemid, $contextid, $component, $filearea, $itemid, array $options=null, $text=null, $forcehttps=false) {
-    global $USER, $DB;
-
-    // Do not merge files, leave it as it was.
-    if ($draftitemid === IGNORE_FILE_MERGE) {
-        // Safely return $text, no need to rewrite pluginfile because this is mostly comming from an external client like the app.
-        return $text;
-    }
-
-    $usercontext = context_user::instance($USER->id);
-    $fs = get_file_storage();
-
-    $options = (array)$options;
-    if (!isset($options['subdirs'])) {
-        $options['subdirs'] = false;
-    }
-    if (!isset($options['maxfiles'])) {
-        $options['maxfiles'] = -1; // unlimited
-    }
-    if (!isset($options['maxbytes']) || $options['maxbytes'] == USER_CAN_IGNORE_FILE_SIZE_LIMITS) {
-        $options['maxbytes'] = 0; // unlimited
-    }
-    if (!isset($options['areamaxbytes'])) {
-        $options['areamaxbytes'] = FILE_AREA_MAX_BYTES_UNLIMITED; // Unlimited.
-    }
-    $allowreferences = true;
-    if (isset($options['return_types']) && !($options['return_types'] & (FILE_REFERENCE | FILE_CONTROLLED_LINK))) {
-        // we assume that if $options['return_types'] is NOT specified, we DO allow references.
-        // this is not exactly right. BUT there are many places in code where filemanager options
-        // are not passed to file_save_draft_area_files()
-        $allowreferences = false;
-    }
-
-    // Check if the user has copy-pasted from other draft areas. Those files will be located in different draft
-    // areas and need to be copied into the current draft area.
-    $text = file_merge_draft_areas($draftitemid, $usercontext->id, $text, $forcehttps);
-
-    // Check if the draft area has exceeded the authorised limit. This should never happen as validation
-    // should have taken place before, unless the user is doing something nauthly. If so, let's just not save
-    // anything at all in the next area.
-    if (file_is_draft_area_limit_reached($draftitemid, $options['areamaxbytes'])) {
-        return null;
-    }
-
-    $draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id');
-    $oldfiles   = $fs->get_area_files($contextid, $component, $filearea, $itemid, 'id');
-
-    // One file in filearea means it is empty (it has only top-level directory '.').
-    if (count($draftfiles) > 1 || count($oldfiles) > 1) {
-        // we have to merge old and new files - we want to keep file ids for files that were not changed
-        // we change time modified for all new and changed files, we keep time created as is
-
-        $newhashes = array();
-        $filecount = 0;
-        $context = context::instance_by_id($contextid, MUST_EXIST);
-        foreach ($draftfiles as $file) {
-            if (!$options['subdirs'] && $file->get_filepath() !== '/') {
-                continue;
-            }
-            if (!$allowreferences && $file->is_external_file()) {
-                continue;
-            }
-            if (!$file->is_directory()) {
-                // Check to see if this file was uploaded by someone who can ignore the file size limits.
-                $fileusermaxbytes = get_user_max_upload_file_size($context, $options['maxbytes'], 0, 0, $file->get_userid());
-                if ($fileusermaxbytes != USER_CAN_IGNORE_FILE_SIZE_LIMITS
-                        && ($options['maxbytes'] and $options['maxbytes'] < $file->get_filesize())) {
-                    // Oversized file.
-                    continue;
-                }
-                if ($options['maxfiles'] != -1 and $options['maxfiles'] <= $filecount) {
-                    // more files - should not get here at all
-                    continue;
-                }
-                $filecount++;
-            }
-            $newhash = $fs->get_pathname_hash($contextid, $component, $filearea, $itemid, $file->get_filepath(), $file->get_filename());
-            $newhashes[$newhash] = $file;
-        }
-
-        // Loop through oldfiles and decide which we need to delete and which to update.
-        // After this cycle the array $newhashes will only contain the files that need to be added.
-        foreach ($oldfiles as $oldfile) {
-            $oldhash = $oldfile->get_pathnamehash();
-            if (!isset($newhashes[$oldhash])) {
-                // delete files not needed any more - deleted by user
-                $oldfile->delete();
-                continue;
-            }
-
-            $newfile = $newhashes[$oldhash];
-            // Now we know that we have $oldfile and $newfile for the same path.
-            // Let's check if we can update this file or we need to delete and create.
-            if ($newfile->is_directory()) {
-                // Directories are always ok to just update.
-            } else if (($source = @unserialize($newfile->get_source())) && isset($source->original)) {
-                // File has the 'original' - we need to update the file (it may even have not been changed at all).
-                $original = file_storage::unpack_reference($source->original);
-                if ($original['filename'] !== $oldfile->get_filename() || $original['filepath'] !== $oldfile->get_filepath()) {
-                    // Very odd, original points to another file. Delete and create file.
-                    $oldfile->delete();
-                    continue;
-                }
-            } else {
-                // The same file name but absence of 'original' means that file was deteled and uploaded again.
-                // By deleting and creating new file we properly manage all existing references.
-                $oldfile->delete();
-                continue;
-            }
-
-            // status changed, we delete old file, and create a new one
-            if ($oldfile->get_status() != $newfile->get_status()) {
-                // file was changed, use updated with new timemodified data
-                $oldfile->delete();
-                // This file will be added later
-                continue;
-            }
-
-            // Updated author
-            if ($oldfile->get_author() != $newfile->get_author()) {
-                $oldfile->set_author($newfile->get_author());
-            }
-            // Updated license
-            if ($oldfile->get_license() != $newfile->get_license()) {
-                $oldfile->set_license($newfile->get_license());
-            }
-
-            // Updated file source
-            // Field files.source for draftarea files contains serialised object with source and original information.
-            // We only store the source part of it for non-draft file area.
-            $newsource = $newfile->get_source();
-            if ($source = @unserialize($newfile->get_source())) {
-                $newsource = $source->source;
-            }
-            if ($oldfile->get_source() !== $newsource) {
-                $oldfile->set_source($newsource);
-            }
-
-            // Updated sort order
-            if ($oldfile->get_sortorder() != $newfile->get_sortorder()) {
-                $oldfile->set_sortorder($newfile->get_sortorder());
-            }
-
-            // Update file timemodified
-            if ($oldfile->get_timemodified() != $newfile->get_timemodified()) {
-                $oldfile->set_timemodified($newfile->get_timemodified());
-            }
-
-            // Replaced file content
-            if (!$oldfile->is_directory() &&
-                    ($oldfile->get_contenthash() != $newfile->get_contenthash() ||
-                    $oldfile->get_filesize() != $newfile->get_filesize() ||
-                    $oldfile->get_referencefileid() != $newfile->get_referencefileid() ||
-                    $oldfile->get_userid() != $newfile->get_userid())) {
-                $oldfile->replace_file_with($newfile);
-            }
-
-            // unchanged file or directory - we keep it as is
-            unset($newhashes[$oldhash]);
-        }
-
-        // Add fresh file or the file which has changed status
-        // the size and subdirectory tests are extra safety only, the UI should prevent it
-        foreach ($newhashes as $file) {
-            $file_record = array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid, 'timemodified'=>time());
-            if ($source = @unserialize($file->get_source())) {
-                // Field files.source for draftarea files contains serialised object with source and original information.
-                // We only store the source part of it for non-draft file area.
-                $file_record['source'] = $source->source;
-            }
-
-            if ($file->is_external_file()) {
-                $repoid = $file->get_repository_id();
-                if (!empty($repoid)) {
-                    $context = context::instance_by_id($contextid, MUST_EXIST);
-                    $repo = repository::get_repository_by_id($repoid, $context);
-                    if (!empty($options)) {
-                        $repo->options = $options;
-                    }
-                    $file_record['repositoryid'] = $repoid;
-                    // This hook gives the repo a place to do some house cleaning, and update the $reference before it's saved
-                    // to the file store. E.g. transfer ownership of the file to a system account etc.
-                    $reference = $repo->reference_file_selected($file->get_reference(), $context, $component, $filearea, $itemid);
-
-                    $file_record['reference'] = $reference;
-                }
-            }
-
-            // Changes for PDFAnnotator.
-            $newentry = $fs->create_file_from_storedfile($file_record, $file);
-            // Checks if the file size exceeds the max size of files in the PDFAnnotator setting.
-            $maxfilesize = get_config('mod_pdfannotator', 'maxbytes');
-            if ($maxfilesize != 0 && $maxfilesize < $newentry->get_filesize()) {
-                $params = new stdClass();
-                $params->filename = $newentry->get_filename();
-                $params->filesize = $newentry->get_filesize();
-                $params->maxfilesize = $maxfilesize;
-                throw new  Error(get_string('error:maxsizeoffiles', 'mod_pdfannotator', $params));
-            }
-            // Changes for PDFAnnotator.
-            $embeddedfile_pdfannotator = new stdClass();
-            $embeddedfile_pdfannotator->fileid = $newentry->get_id();
-            $embeddedfile_pdfannotator->commentid = $itemid;
-            $embeddedfile_pdfannotator->id = $DB->insert_record('pdfannotator_embeddedfiles', $embeddedfile_pdfannotator);
-            // Set the sortorder for the mapping with pdfannotator_embeddedfiles table.
-            $newentry->set_sortorder($embeddedfile_pdfannotator->id);
-        }
-    }
-
-    // note: do not purge the draft area - we clean up areas later in cron,
-    //       the reason is that user might press submit twice and they would loose the files,
-    //       also sometimes we might want to use hacks that save files into two different areas
-
-    if (is_null($text)) {
-        return null;
-    } else {
-        return file_rewrite_urls_to_pluginfile($text, $draftitemid, $forcehttps);
-    }
-}
-
 function pdfannotator_get_instance_name($id) {
 
     global $DB;
diff --git a/shared/index.js b/shared/index.js
index 014762ddb1562950cdce5404060c0f4d5a0e4299..8e3a88b1866fe4c3ab5b489cf597221605ddbe4d 100644
--- a/shared/index.js
+++ b/shared/index.js
@@ -238,9 +238,10 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                     if(data.status === "success") {
                         if(deletionInfo) {
                             notification.addNotification({
-                                        message: M.util.get_string('annotationDeleted', 'pdfannotator'),
-                                        type: "success"
+                                message: M.util.get_string('annotationDeleted', 'pdfannotator'),
+                                type: "success"
                             });
+                            setTimeoutNotification();
                         }                            
                         var node = document.querySelector('[data-pdf-annotate-id="'+data.deleteannotation+'"]');
                         if(node){
@@ -251,8 +252,8 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                         }
                     } else if (data.status === 'error') {
                             notification.addNotification({                                   
-                                        message: M.util.get_string('deletionForbidden', 'pdfannotator') + data.reason,
-                                        type: "error"
+                                message: M.util.get_string('deletionForbidden', 'pdfannotator') + data.reason,
+                                type: "error"
                             });
                     }
 
@@ -360,6 +361,7 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                                 message: M.util.get_string('commentDeleted', 'pdfannotator'),
                                 type: "success"
                             });
+                            setTimeoutNotification();
 
                             // If the predecessor comment was marked as deleted, remove it from DOM as well
                             // (This is currently irrelevant, because we jump back to overview after deletion, but I'd prefer to stay in the thread.)
@@ -413,18 +415,13 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                             message: M.util.get_string('successfullyHidden', 'pdfannotator'),
                             type: "success"
                         });
+                        setTimeoutNotification();
                     } else {
                         notification.addNotification({
                             message: M.util.get_string('error:hideComment','pdfannotator'),
                             type: "error"
                         });                                        
                     }
-                    setTimeout(function(){
-                        let notificationpanel = document.getElementById("user-notifications");
-                        while (notificationpanel.hasChildNodes()) {
-                            notificationpanel.removeChild(notificationpanel.firstChild);
-                        }
-                    }, 5000);
                 });
             },
             /**
@@ -450,18 +447,13 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                             message: M.util.get_string('successfullyRedisplayed', 'pdfannotator'),
                             type: "success"
                         });
+                        setTimeoutNotification();
                     } else {
                         notification.addNotification({
                             message: M.util.get_string('error:redisplayComment','pdfannotator'),
                             type: "error"
                         });                                        
                     }
-                    setTimeout(function(){
-                        let notificationpanel = document.getElementById("user-notifications");
-                        while (notificationpanel.hasChildNodes()) {
-                            notificationpanel.removeChild(notificationpanel.firstChild);
-                        }
-                    }, 5000);
                 });
 
             },
@@ -593,12 +585,6 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                             message: message,
                             type: "info"
                         });
-                        setTimeout(function(){
-                            let notificationpanel = document.getElementById("user-notifications");
-                            while (notificationpanel.hasChildNodes()) {  
-                                notificationpanel.removeChild(notificationpanel.firstChild);
-                            } 
-                        }, 3000);
                     }
                 });  
             },
@@ -951,24 +937,11 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                                         message: M.util.get_string('infonocomments','pdfannotator'),
                                         type: "info"
                                     });
-                                    setTimeout(function(){
-                                        let notificationpanel = document.getElementById("user-notifications");
-                                        while (notificationpanel.hasChildNodes()) {  
-                                            notificationpanel.removeChild(notificationpanel.firstChild);
-                                        } 
-                                    }, 3000);
-
                                 } else if(data.status === 'error') {
                                     notification.addNotification({
                                         message: M.util.get_string('error:printcomments','pdfannotator'),
                                         type: "error"
                                     });
-                                    setTimeout(function(){
-                                        let notificationpanel = document.getElementById("user-notifications");
-                                        while (notificationpanel.hasChildNodes()) {  
-                                            notificationpanel.removeChild(notificationpanel.firstChild);
-                                        } 
-                                    }, 3000);
                                 } 
                             });  
                     } // end of function openCommentsCallback
@@ -1639,6 +1612,7 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                                         message: M.util.get_string('successfullyUnsubscribed', 'pdfannotator'),
                                         type: "success"
                                 });
+                                setTimeoutNotification()
                             } else if(data.status == 'error') {
                                 notification.addNotification({
                                     message: M.util.get_string('error:unsubscribe','pdfannotator'),
@@ -1651,11 +1625,12 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                 } else {
                     _2.default.getStoreAdapter().subscribeQuestion(RENDER_OPTIONS.documentId, comment.annotation)
                         .then(function(data){
-                                if(data.status === "success") {
+                            if(data.status === "success") {
                                 notification.addNotification({
                                         message: M.util.get_string('successfullySubscribed', 'pdfannotator'),
                                         type: "success"
                                 });
+                                setTimeoutNotification();
                             } else if(data.status == 'error') {
                                 notification.addNotification({
                                     message: M.util.get_string('error:subscribe','pdfannotator'),
@@ -1669,12 +1644,6 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                 comment.issubscribed = !comment.issubscribed;
                 i.toggleClass("fa-bell");
                 i.toggleClass("fa-bell-slash");
-                setTimeout(function () {
-                        let notificationpanel = document.getElementById("user-notifications");
-                        while (notificationpanel.hasChildNodes()) {
-                            notificationpanel.removeChild(notificationpanel.firstChild);
-                        }
-                }, 3000);
             });            
             }
             
@@ -1812,6 +1781,7 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                                                 message: M.util.get_string('successfullyEdited', 'pdfannotator'),
                                                 type: "success"
                                             });
+                                            setTimeoutNotification();
                                         } else {
                                             notification.addNotification({
                                                 message: M.util.get_string('error:editComment','pdfannotator'),
@@ -2013,13 +1983,6 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                                 message: M.util.get_string('error:getComments','pdfannotator'),
                                 type: "error"
                             });
-
-                            setTimeout(function(){
-                                let notificationpanel = document.getElementById("user-notifications");
-                                while (notificationpanel.hasChildNodes()) {
-                                    notificationpanel.removeChild(notificationpanel.firstChild);
-                                }
-                            }, 4000);
                         });
                     })();
                 }else{      
diff --git a/shared/locallib.js b/shared/locallib.js
index bc75be5d828c5c69bad36dc53d8a87d0de36b83e..19ac66904f75d294d1fb547d594de82acc73e90d 100644
--- a/shared/locallib.js
+++ b/shared/locallib.js
@@ -224,4 +224,13 @@ function checkOnlyOneCheckbox( Y ) {
             }
         });
     }
+}
+
+function setTimeoutNotification(){
+    setTimeout(function(){
+        let notificationpanel = document.getElementById("user-notifications");
+        while (notificationpanel.hasChildNodes()) {  
+            notificationpanel.removeChild(notificationpanel.firstChild);
+        } 
+    }, 10000);
 }
\ No newline at end of file
diff --git a/version.php b/version.php
index 1350aa61f7610854ec3aaf5a4fa92bb36b87c8ed..b0dd6a6880ac0991ad11e46be8233be1ece9f3c2 100644
--- a/version.php
+++ b/version.php
@@ -25,7 +25,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $plugin->component = 'mod_pdfannotator';
-$plugin->version   = 2022110200;
+$plugin->version   = 2022110201;
 $plugin->release  = 'PDF Annotator v1.4 release 11';
 $plugin->requires  = 2021051700;
 $plugin->maturity  = MATURITY_STABLE;