From 401710c3bd83ae2b0702b23753e80e0afd36f4c2 Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Tue, 8 Oct 2024 07:01:49 +0530
Subject: [PATCH 01/20] fix(app): Fix proxy modal test

---
 src/components/ProxyDialog.vue | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/src/components/ProxyDialog.vue b/src/components/ProxyDialog.vue
index fc92359b9..62eb6f2bc 100644
--- a/src/components/ProxyDialog.vue
+++ b/src/components/ProxyDialog.vue
@@ -130,6 +130,27 @@ export default {
         this.modal = new Modal(this.$refs.modal);
     },
 
+    beforeRouteLeave(to, from, next) {
+        if (this.modal) {
+            this.modal.hide();
+        }
+        next();
+    },
+
+    watch: {
+        $route(to, from) {
+            if (this.modal) {
+                this.modal.hide();
+            }
+        }
+    },
+
+    beforeUnmount() {
+        if (this.modal) {
+            this.modal.dispose();
+        }
+    },
+
     methods: {
         /**
          * Show dialog to confirm deletion

From 1dceb96c7c81941f11b454dfc5c36b7bd707cd5e Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Tue, 8 Oct 2024 07:17:31 +0530
Subject: [PATCH 02/20] fix(app): notification modal fix

---
 src/components/NotificationDialog.vue | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue
index 864cbf5f4..b34b5f8ad 100644
--- a/src/components/NotificationDialog.vue
+++ b/src/components/NotificationDialog.vue
@@ -226,10 +226,26 @@ export default {
                 this.notification.name = this.getUniqueDefaultName(to);
             }
         },
+        $route(to, from) {
+            if (this.modal) {
+                this.modal.hide();
+            }
+        }
     },
     mounted() {
         this.modal = new Modal(this.$refs.modal);
     },
+    beforeUnmount() {
+        if (this.modal) {
+            this.modal.dispose();
+        }
+    },
+    beforeRouteLeave(to, from, next) {
+        if (this.modal) {
+            this.modal.hide();
+        }
+        next();
+    },
     methods: {
 
         /**

From 45b6c8a91d084695b3ff1e144129682cd9f8161e Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Tue, 8 Oct 2024 07:33:18 +0530
Subject: [PATCH 03/20] Fix scroll lock

when the modal is opened, its sets overflow hidden, remove this style so as to unfreeze it
---
 src/components/ProxyDialog.vue | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/src/components/ProxyDialog.vue b/src/components/ProxyDialog.vue
index 62eb6f2bc..718bdb5f5 100644
--- a/src/components/ProxyDialog.vue
+++ b/src/components/ProxyDialog.vue
@@ -131,24 +131,18 @@ export default {
     },
 
     beforeRouteLeave(to, from, next) {
-        if (this.modal) {
-            this.modal.hide();
-        }
+        this.cleanupModal();
         next();
     },
 
     watch: {
         $route(to, from) {
-            if (this.modal) {
-                this.modal.hide();
-            }
+            this.cleanupModal();
         }
     },
 
     beforeUnmount() {
-        if (this.modal) {
-            this.modal.dispose();
-        }
+        this.cleanupModal();
     },
 
     methods: {
@@ -230,6 +224,20 @@ export default {
                 }
             });
         },
+
+        /**
+         * Clean up modal and restore scroll behavior
+         * @returns {void}
+         */
+         cleanupModal() {
+            if (this.modal) {
+                this.modal.hide();
+                this.modal.dispose();
+            }
+            document.body.classList.remove('modal-open');
+            document.body.style.paddingRight = '';
+            document.body.style.overflow = '';
+        }
     },
 };
 </script>

From da831893de8e56072c0e3bebe0128b5f21309b55 Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Tue, 8 Oct 2024 07:37:35 +0530
Subject: [PATCH 04/20] fix scroll in notfication

---
 src/components/NotificationDialog.vue | 28 ++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue
index b34b5f8ad..fd9042a5e 100644
--- a/src/components/NotificationDialog.vue
+++ b/src/components/NotificationDialog.vue
@@ -226,24 +226,20 @@ export default {
                 this.notification.name = this.getUniqueDefaultName(to);
             }
         },
+        watch: {
         $route(to, from) {
-            if (this.modal) {
-                this.modal.hide();
-            }
+            this.cleanupModal();
         }
     },
+    },
     mounted() {
         this.modal = new Modal(this.$refs.modal);
     },
     beforeUnmount() {
-        if (this.modal) {
-            this.modal.dispose();
-        }
+        this.cleanupModal();
     },
     beforeRouteLeave(to, from, next) {
-        if (this.modal) {
-            this.modal.hide();
-        }
+        this.cleanupModal();
         next();
     },
     methods: {
@@ -350,6 +346,20 @@ export default {
                 });
             } while (this.$root.notificationList.find(it => it.name === name));
             return name;
+        },
+
+        /**
+         * Clean up modal and restore scroll behavior
+         * @returns {void}
+         */
+         cleanupModal() {
+            if (this.modal) {
+                this.modal.hide();
+                this.modal.dispose();
+            }
+            document.body.classList.remove('modal-open');
+            document.body.style.paddingRight = '';
+            document.body.style.overflow = '';
         }
     },
 };

From e2ce0e38a68a7eb8432e98993e8ec2b411efe45e Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Tue, 8 Oct 2024 08:23:07 +0530
Subject: [PATCH 05/20] update

---
 src/components/CreateGroupDialog.vue  | 28 +++++++++++++++++++++++++
 src/components/NotificationDialog.vue |  7 +++++--
 src/components/ProxyDialog.vue        |  7 +++++--
 src/components/TagsManager.vue        | 30 +++++++++++++++++++++++++++
 4 files changed, 68 insertions(+), 4 deletions(-)

diff --git a/src/components/CreateGroupDialog.vue b/src/components/CreateGroupDialog.vue
index ba7fe6eb7..711369755 100644
--- a/src/components/CreateGroupDialog.vue
+++ b/src/components/CreateGroupDialog.vue
@@ -42,6 +42,18 @@ export default {
     mounted() {
         this.modal = new Modal(this.$refs.modal);
     },
+    watch: {
+        $route(to, from) {
+            this.cleanupModal();
+        }
+    },
+    beforeUnmount() {
+        this.cleanupModal();
+    },
+    beforeRouteLeave(to, from, next) {
+        this.cleanupModal();
+        next();
+    },
     methods: {
         /**
          * Show the confirm dialog
@@ -58,6 +70,22 @@ export default {
             this.$emit("added", this.groupName);
             this.modal.hide();
         },
+        /**
+         * Clean up modal and restore scroll behavior
+         * @returns {void}
+         */
+         cleanupModal() {
+            if (this.modal) {
+                try {
+                    this.modal.hide();
+                } catch (e) {
+                    console.warn("Modal hide failed:", e);
+                }
+            }
+            document.body.classList.remove('modal-open');
+            document.body.style.paddingRight = '';
+            document.body.style.overflow = '';
+        }
     },
 };
 </script>
diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue
index fd9042a5e..41b179780 100644
--- a/src/components/NotificationDialog.vue
+++ b/src/components/NotificationDialog.vue
@@ -354,8 +354,11 @@ export default {
          */
          cleanupModal() {
             if (this.modal) {
-                this.modal.hide();
-                this.modal.dispose();
+                try {
+                    this.modal.hide();
+                } catch (e) {
+                    console.warn("Modal hide failed:", e);
+                }
             }
             document.body.classList.remove('modal-open');
             document.body.style.paddingRight = '';
diff --git a/src/components/ProxyDialog.vue b/src/components/ProxyDialog.vue
index 718bdb5f5..35c752a1b 100644
--- a/src/components/ProxyDialog.vue
+++ b/src/components/ProxyDialog.vue
@@ -231,8 +231,11 @@ export default {
          */
          cleanupModal() {
             if (this.modal) {
-                this.modal.hide();
-                this.modal.dispose();
+                try {
+                    this.modal.hide();
+                } catch (e) {
+                    console.warn("Modal hide failed:", e);
+                }
             }
             document.body.classList.remove('modal-open');
             document.body.style.paddingRight = '';
diff --git a/src/components/TagsManager.vue b/src/components/TagsManager.vue
index 19c8e481b..398cd8bd7 100644
--- a/src/components/TagsManager.vue
+++ b/src/components/TagsManager.vue
@@ -248,6 +248,20 @@ export default {
         this.modal = new Modal(this.$refs.modal);
         this.getExistingTags();
     },
+    beforeRouteLeave(to, from, next) {
+        this.cleanupModal();
+        next();
+    },
+
+    watch: {
+        $route(to, from) {
+            this.cleanupModal();
+        }
+    },
+
+    beforeUnmount() {
+        this.cleanupModal();
+    },
     methods: {
         /**
          * Show the add tag dialog
@@ -459,6 +473,22 @@ export default {
             this.newTags = [];
             this.deleteTags = [];
             this.processing = false;
+        },
+        /**
+         * Clean up modal and restore scroll behavior
+         * @returns {void}
+         */
+         cleanupModal() {
+            if (this.modal) {
+                try {
+                    this.modal.hide();
+                } catch (e) {
+                    console.warn("Modal hide failed:", e);
+                }
+            }
+            document.body.classList.remove('modal-open');
+            document.body.style.paddingRight = '';
+            document.body.style.overflow = '';
         }
     },
 };

From 72849de1b467f21e550858982c071b8b669c981c Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Tue, 8 Oct 2024 08:43:30 +0530
Subject: [PATCH 06/20] fix lint

---
 src/components/CreateGroupDialog.vue  |  8 ++++----
 src/components/NotificationDialog.vue | 10 ++++------
 src/components/ProxyDialog.vue        |  8 ++++----
 src/components/TagsManager.vue        |  8 ++++----
 4 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/src/components/CreateGroupDialog.vue b/src/components/CreateGroupDialog.vue
index 711369755..ee37fb0b2 100644
--- a/src/components/CreateGroupDialog.vue
+++ b/src/components/CreateGroupDialog.vue
@@ -74,7 +74,7 @@ export default {
          * Clean up modal and restore scroll behavior
          * @returns {void}
          */
-         cleanupModal() {
+        cleanupModal() {
             if (this.modal) {
                 try {
                     this.modal.hide();
@@ -82,9 +82,9 @@ export default {
                     console.warn("Modal hide failed:", e);
                 }
             }
-            document.body.classList.remove('modal-open');
-            document.body.style.paddingRight = '';
-            document.body.style.overflow = '';
+            document.body.classList.remove("modal-open");
+            document.body.style.paddingRight = "";
+            document.body.style.overflow = "";
         }
     },
 };
diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue
index 41b179780..4641fe9ab 100644
--- a/src/components/NotificationDialog.vue
+++ b/src/components/NotificationDialog.vue
@@ -226,12 +226,10 @@ export default {
                 this.notification.name = this.getUniqueDefaultName(to);
             }
         },
-        watch: {
         $route(to, from) {
             this.cleanupModal();
         }
     },
-    },
     mounted() {
         this.modal = new Modal(this.$refs.modal);
     },
@@ -352,7 +350,7 @@ export default {
          * Clean up modal and restore scroll behavior
          * @returns {void}
          */
-         cleanupModal() {
+        cleanupModal() {
             if (this.modal) {
                 try {
                     this.modal.hide();
@@ -360,9 +358,9 @@ export default {
                     console.warn("Modal hide failed:", e);
                 }
             }
-            document.body.classList.remove('modal-open');
-            document.body.style.paddingRight = '';
-            document.body.style.overflow = '';
+            document.body.classList.remove("modal-open");
+            document.body.style.paddingRight = "";
+            document.body.style.overflow = "";
         }
     },
 };
diff --git a/src/components/ProxyDialog.vue b/src/components/ProxyDialog.vue
index 35c752a1b..8c212f265 100644
--- a/src/components/ProxyDialog.vue
+++ b/src/components/ProxyDialog.vue
@@ -229,7 +229,7 @@ export default {
          * Clean up modal and restore scroll behavior
          * @returns {void}
          */
-         cleanupModal() {
+        cleanupModal() {
             if (this.modal) {
                 try {
                     this.modal.hide();
@@ -237,9 +237,9 @@ export default {
                     console.warn("Modal hide failed:", e);
                 }
             }
-            document.body.classList.remove('modal-open');
-            document.body.style.paddingRight = '';
-            document.body.style.overflow = '';
+            document.body.classList.remove("modal-open");
+            document.body.style.paddingRight = "";
+            document.body.style.overflow = "";
         }
     },
 };
diff --git a/src/components/TagsManager.vue b/src/components/TagsManager.vue
index 398cd8bd7..b4938304a 100644
--- a/src/components/TagsManager.vue
+++ b/src/components/TagsManager.vue
@@ -478,7 +478,7 @@ export default {
          * Clean up modal and restore scroll behavior
          * @returns {void}
          */
-         cleanupModal() {
+        cleanupModal() {
             if (this.modal) {
                 try {
                     this.modal.hide();
@@ -486,9 +486,9 @@ export default {
                     console.warn("Modal hide failed:", e);
                 }
             }
-            document.body.classList.remove('modal-open');
-            document.body.style.paddingRight = '';
-            document.body.style.overflow = '';
+            document.body.classList.remove("modal-open");
+            document.body.style.paddingRight = "";
+            document.body.style.overflow = "";
         }
     },
 };

From 56b3cf412b7758ddbfbc6226c47842df180e5f16 Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Tue, 8 Oct 2024 09:10:36 +0530
Subject: [PATCH 07/20] warnings fix :)

---
 src/components/CreateGroupDialog.vue | 14 +++++++-------
 src/components/ProxyDialog.vue       | 19 +++++++------------
 src/components/TagsManager.vue       | 18 ++++++++----------
 3 files changed, 22 insertions(+), 29 deletions(-)

diff --git a/src/components/CreateGroupDialog.vue b/src/components/CreateGroupDialog.vue
index ee37fb0b2..326107643 100644
--- a/src/components/CreateGroupDialog.vue
+++ b/src/components/CreateGroupDialog.vue
@@ -33,27 +33,27 @@
 import { Modal } from "bootstrap";
 
 export default {
+    beforeRouteLeave(to, from, next) {
+        this.cleanupModal();
+        next();
+    },
     props: {},
     emits: [ "added" ],
     data: () => ({
         modal: null,
         groupName: null,
     }),
-    mounted() {
-        this.modal = new Modal(this.$refs.modal);
-    },
     watch: {
         $route(to, from) {
             this.cleanupModal();
         }
     },
+    mounted() {
+        this.modal = new Modal(this.$refs.modal);
+    },
     beforeUnmount() {
         this.cleanupModal();
     },
-    beforeRouteLeave(to, from, next) {
-        this.cleanupModal();
-        next();
-    },
     methods: {
         /**
          * Show the confirm dialog
diff --git a/src/components/ProxyDialog.vue b/src/components/ProxyDialog.vue
index 8c212f265..a6f6cce5a 100644
--- a/src/components/ProxyDialog.vue
+++ b/src/components/ProxyDialog.vue
@@ -105,6 +105,10 @@ export default {
     components: {
         Confirm,
     },
+    beforeRouteLeave(to, from, next) {
+        this.cleanupModal();
+        next();
+    },
     props: {},
     emits: [ "added" ],
     data() {
@@ -125,26 +129,17 @@ export default {
             }
         };
     },
-
-    mounted() {
-        this.modal = new Modal(this.$refs.modal);
-    },
-
-    beforeRouteLeave(to, from, next) {
-        this.cleanupModal();
-        next();
-    },
-
     watch: {
         $route(to, from) {
             this.cleanupModal();
         }
     },
-
+    mounted() {
+        this.modal = new Modal(this.$refs.modal);
+    },
     beforeUnmount() {
         this.cleanupModal();
     },
-
     methods: {
         /**
          * Show dialog to confirm deletion
diff --git a/src/components/TagsManager.vue b/src/components/TagsManager.vue
index b4938304a..2cc3549c9 100644
--- a/src/components/TagsManager.vue
+++ b/src/components/TagsManager.vue
@@ -155,6 +155,10 @@ export default {
         Tag,
         VueMultiselect,
     },
+    beforeRouteLeave(to, from, next) {
+        this.cleanupModal();
+        next();
+    },
     props: {
         /**
          * Array of tags to be pre-selected
@@ -244,21 +248,15 @@ export default {
             };
         },
     },
-    mounted() {
-        this.modal = new Modal(this.$refs.modal);
-        this.getExistingTags();
-    },
-    beforeRouteLeave(to, from, next) {
-        this.cleanupModal();
-        next();
-    },
-
     watch: {
         $route(to, from) {
             this.cleanupModal();
         }
     },
-
+    mounted() {
+        this.modal = new Modal(this.$refs.modal);
+        this.getExistingTags();
+    },
     beforeUnmount() {
         this.cleanupModal();
     },

From 0d2b380f44f7541e836b1eaaa464878be029de11 Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Tue, 8 Oct 2024 09:31:05 +0530
Subject: [PATCH 08/20] Update NotificationDialog.vue

i hadnt saved this T_T
---
 src/components/NotificationDialog.vue | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue
index 4641fe9ab..dffe2e031 100644
--- a/src/components/NotificationDialog.vue
+++ b/src/components/NotificationDialog.vue
@@ -80,6 +80,10 @@ export default {
     components: {
         Confirm,
     },
+    beforeRouteLeave(to, from, next) {
+        this.cleanupModal();
+        next();
+    },
     props: {},
     emits: [ "added" ],
     data() {
@@ -236,10 +240,6 @@ export default {
     beforeUnmount() {
         this.cleanupModal();
     },
-    beforeRouteLeave(to, from, next) {
-        this.cleanupModal();
-        next();
-    },
     methods: {
 
         /**

From 95a9e0a096aee1f1b205d5d25a2ba7c1d51bdf4d Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Tue, 8 Oct 2024 19:09:21 +0530
Subject: [PATCH 09/20] remove duplicate code

---
 src/components/CreateGroupDialog.vue  | 12 ------------
 src/components/NotificationDialog.vue | 10 ----------
 src/components/ProxyDialog.vue        | 12 ------------
 src/components/TagsManager.vue        | 12 ------------
 4 files changed, 46 deletions(-)

diff --git a/src/components/CreateGroupDialog.vue b/src/components/CreateGroupDialog.vue
index 326107643..8bac1ccd0 100644
--- a/src/components/CreateGroupDialog.vue
+++ b/src/components/CreateGroupDialog.vue
@@ -33,21 +33,12 @@
 import { Modal } from "bootstrap";
 
 export default {
-    beforeRouteLeave(to, from, next) {
-        this.cleanupModal();
-        next();
-    },
     props: {},
     emits: [ "added" ],
     data: () => ({
         modal: null,
         groupName: null,
     }),
-    watch: {
-        $route(to, from) {
-            this.cleanupModal();
-        }
-    },
     mounted() {
         this.modal = new Modal(this.$refs.modal);
     },
@@ -82,9 +73,6 @@ export default {
                     console.warn("Modal hide failed:", e);
                 }
             }
-            document.body.classList.remove("modal-open");
-            document.body.style.paddingRight = "";
-            document.body.style.overflow = "";
         }
     },
 };
diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue
index dffe2e031..cd001b375 100644
--- a/src/components/NotificationDialog.vue
+++ b/src/components/NotificationDialog.vue
@@ -80,10 +80,6 @@ export default {
     components: {
         Confirm,
     },
-    beforeRouteLeave(to, from, next) {
-        this.cleanupModal();
-        next();
-    },
     props: {},
     emits: [ "added" ],
     data() {
@@ -230,9 +226,6 @@ export default {
                 this.notification.name = this.getUniqueDefaultName(to);
             }
         },
-        $route(to, from) {
-            this.cleanupModal();
-        }
     },
     mounted() {
         this.modal = new Modal(this.$refs.modal);
@@ -358,9 +351,6 @@ export default {
                     console.warn("Modal hide failed:", e);
                 }
             }
-            document.body.classList.remove("modal-open");
-            document.body.style.paddingRight = "";
-            document.body.style.overflow = "";
         }
     },
 };
diff --git a/src/components/ProxyDialog.vue b/src/components/ProxyDialog.vue
index a6f6cce5a..2f7ed7b61 100644
--- a/src/components/ProxyDialog.vue
+++ b/src/components/ProxyDialog.vue
@@ -105,10 +105,6 @@ export default {
     components: {
         Confirm,
     },
-    beforeRouteLeave(to, from, next) {
-        this.cleanupModal();
-        next();
-    },
     props: {},
     emits: [ "added" ],
     data() {
@@ -129,11 +125,6 @@ export default {
             }
         };
     },
-    watch: {
-        $route(to, from) {
-            this.cleanupModal();
-        }
-    },
     mounted() {
         this.modal = new Modal(this.$refs.modal);
     },
@@ -232,9 +223,6 @@ export default {
                     console.warn("Modal hide failed:", e);
                 }
             }
-            document.body.classList.remove("modal-open");
-            document.body.style.paddingRight = "";
-            document.body.style.overflow = "";
         }
     },
 };
diff --git a/src/components/TagsManager.vue b/src/components/TagsManager.vue
index 2cc3549c9..368ea18c2 100644
--- a/src/components/TagsManager.vue
+++ b/src/components/TagsManager.vue
@@ -155,10 +155,6 @@ export default {
         Tag,
         VueMultiselect,
     },
-    beforeRouteLeave(to, from, next) {
-        this.cleanupModal();
-        next();
-    },
     props: {
         /**
          * Array of tags to be pre-selected
@@ -248,11 +244,6 @@ export default {
             };
         },
     },
-    watch: {
-        $route(to, from) {
-            this.cleanupModal();
-        }
-    },
     mounted() {
         this.modal = new Modal(this.$refs.modal);
         this.getExistingTags();
@@ -484,9 +475,6 @@ export default {
                     console.warn("Modal hide failed:", e);
                 }
             }
-            document.body.classList.remove("modal-open");
-            document.body.style.paddingRight = "";
-            document.body.style.overflow = "";
         }
     },
 };

From 498786eb3922563dbe1318ec88af31446e666137 Mon Sep 17 00:00:00 2001
From: "deepsource-io[bot]"
 <42547082+deepsource-io[bot]@users.noreply.github.com>
Date: Fri, 11 Oct 2024 07:51:20 +0000
Subject: [PATCH 10/20] ci: add .deepsource.toml

---
 .deepsource.toml | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 .deepsource.toml

diff --git a/.deepsource.toml b/.deepsource.toml
new file mode 100644
index 000000000..525c75c6f
--- /dev/null
+++ b/.deepsource.toml
@@ -0,0 +1,31 @@
+version = 1
+
+[[analyzers]]
+name = "php"
+
+[[analyzers]]
+name = "python"
+
+  [analyzers.meta]
+  runtime_version = "3.x.x"
+
+[[analyzers]]
+name = "go"
+
+  [analyzers.meta]
+  import_root = "github.com/mohit-nagaraj/uptime-kuma"
+
+[[analyzers]]
+name = "java"
+
+  [analyzers.meta]
+  runtime_version = "11"
+
+[[analyzers]]
+name = "csharp"
+
+[[analyzers]]
+name = "javascript"
+
+[[analyzers]]
+name = "shell"
\ No newline at end of file

From 87f3c2ef94a60d0ce140447618374b93276769b6 Mon Sep 17 00:00:00 2001
From: "deepsource-io[bot]"
 <42547082+deepsource-io[bot]@users.noreply.github.com>
Date: Fri, 11 Oct 2024 07:59:07 +0000
Subject: [PATCH 11/20] ci: update .deepsource.toml


From 949198d09ea16494c62d79759bba4da5eeb5463e Mon Sep 17 00:00:00 2001
From: "deepsource-autofix[bot]"
 <62050782+deepsource-autofix[bot]@users.noreply.github.com>
Date: Fri, 11 Oct 2024 08:31:13 +0000
Subject: [PATCH 12/20] refactor: fix check for empty string

It is not recommended to use `len` for empty string test.
---
 extra/healthcheck.go | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/extra/healthcheck.go b/extra/healthcheck.go
index f79b3e65b..9687a6630 100644
--- a/extra/healthcheck.go
+++ b/extra/healthcheck.go
@@ -32,20 +32,20 @@ func main() {
 	}
 
 	sslKey := os.Getenv("UPTIME_KUMA_SSL_KEY")
-	if len(sslKey) == 0 {
+	if sslKey == "" {
 		sslKey = os.Getenv("SSL_KEY")
 	}
 
 	sslCert := os.Getenv("UPTIME_KUMA_SSL_CERT")
-	if len(sslCert) == 0 {
+	if sslCert == "" {
 		sslCert = os.Getenv("SSL_CERT")
 	}
 
 	hostname := os.Getenv("UPTIME_KUMA_HOST")
-	if len(hostname) == 0 && !isFreeBSD {
+	if hostname == "" && !isFreeBSD {
 		hostname = os.Getenv("HOST")
 	}
-	if len(hostname) == 0 {
+	if hostname == "" {
 		hostname = "127.0.0.1"
 	}
 
@@ -54,15 +54,15 @@ func main() {
 	if !isK8s {
 		port = os.Getenv("UPTIME_KUMA_PORT")
 	}
-	if len(port) == 0 {
+	if port == "" {
 		port = os.Getenv("PORT")
 	}
-	if len(port) == 0 {
+	if port == "" {
 		port = "3001"
 	}
 
 	protocol := ""
-	if len(sslKey) != 0 && len(sslCert) != 0 {
+	if sslKey != "" && sslCert != "" {
 		protocol = "https"
 	} else {
 		protocol = "http"

From dcb675a343c6b4aa17bc708514434f56a97d31f6 Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Fri, 11 Oct 2024 14:23:35 +0530
Subject: [PATCH 13/20] update

---
 .deepsource.toml | 31 -------------------------------
 1 file changed, 31 deletions(-)
 delete mode 100644 .deepsource.toml

diff --git a/.deepsource.toml b/.deepsource.toml
deleted file mode 100644
index 525c75c6f..000000000
--- a/.deepsource.toml
+++ /dev/null
@@ -1,31 +0,0 @@
-version = 1
-
-[[analyzers]]
-name = "php"
-
-[[analyzers]]
-name = "python"
-
-  [analyzers.meta]
-  runtime_version = "3.x.x"
-
-[[analyzers]]
-name = "go"
-
-  [analyzers.meta]
-  import_root = "github.com/mohit-nagaraj/uptime-kuma"
-
-[[analyzers]]
-name = "java"
-
-  [analyzers.meta]
-  runtime_version = "11"
-
-[[analyzers]]
-name = "csharp"
-
-[[analyzers]]
-name = "javascript"
-
-[[analyzers]]
-name = "shell"
\ No newline at end of file

From 9684d34ad0b534e6a54af4eacb6da72a7e0d49d2 Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Fri, 11 Oct 2024 15:11:13 +0530
Subject: [PATCH 14/20] Revert "refactor: fix check for empty string"

This reverts commit 949198d09ea16494c62d79759bba4da5eeb5463e.
---
 extra/healthcheck.go | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/extra/healthcheck.go b/extra/healthcheck.go
index 9687a6630..f79b3e65b 100644
--- a/extra/healthcheck.go
+++ b/extra/healthcheck.go
@@ -32,20 +32,20 @@ func main() {
 	}
 
 	sslKey := os.Getenv("UPTIME_KUMA_SSL_KEY")
-	if sslKey == "" {
+	if len(sslKey) == 0 {
 		sslKey = os.Getenv("SSL_KEY")
 	}
 
 	sslCert := os.Getenv("UPTIME_KUMA_SSL_CERT")
-	if sslCert == "" {
+	if len(sslCert) == 0 {
 		sslCert = os.Getenv("SSL_CERT")
 	}
 
 	hostname := os.Getenv("UPTIME_KUMA_HOST")
-	if hostname == "" && !isFreeBSD {
+	if len(hostname) == 0 && !isFreeBSD {
 		hostname = os.Getenv("HOST")
 	}
-	if hostname == "" {
+	if len(hostname) == 0 {
 		hostname = "127.0.0.1"
 	}
 
@@ -54,15 +54,15 @@ func main() {
 	if !isK8s {
 		port = os.Getenv("UPTIME_KUMA_PORT")
 	}
-	if port == "" {
+	if len(port) == 0 {
 		port = os.Getenv("PORT")
 	}
-	if port == "" {
+	if len(port) == 0 {
 		port = "3001"
 	}
 
 	protocol := ""
-	if sslKey != "" && sslCert != "" {
+	if len(sslKey) != 0 && len(sslCert) != 0 {
 		protocol = "https"
 	} else {
 		protocol = "http"

From f010d7f874441cc6dba2804e9250913e30ecb30f Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Sat, 12 Oct 2024 00:54:37 +0530
Subject: [PATCH 15/20] feat(app): #5120 Upcoming heartbeat timer

---
 src/pages/Details.vue | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/src/pages/Details.vue b/src/pages/Details.vue
index 17d32365c..50f4ec0dd 100644
--- a/src/pages/Details.vue
+++ b/src/pages/Details.vue
@@ -76,7 +76,7 @@
                 <div class="row">
                     <div class="col-md-8">
                         <HeartbeatBar :monitor-id="monitor.id" />
-                        <span class="word">{{ $t("checkEverySecond", [ monitor.interval ]) }}</span>
+                        <div><span v-if="monitor.active" class="mr-2">Next in {{ formattedTime }}&nbsp;</span><span class="word">({{ $t("checkEverySecond", [ monitor.interval ]) }})</span></div>
                     </div>
                     <div class="col-md-4 text-center">
                         <span class="badge rounded-pill" :class=" 'bg-' + status.color " style="font-size: 30px;" data-testid="monitor-status">{{ status.text }}</span>
@@ -293,6 +293,7 @@ import "prismjs/components/prism-css";
 import { PrismEditor } from "vue-prism-editor";
 import "vue-prism-editor/dist/prismeditor.min.css";
 import ScreenshotDialog from "../components/ScreenshotDialog.vue";
+import dayjs from "dayjs";
 
 export default {
     components: {
@@ -313,6 +314,7 @@ export default {
         return {
             page: 1,
             perPage: 25,
+            timeRemaining: 0,
             heartBeatList: [],
             toggleCertInfoBox: false,
             showPingChartBox: true,
@@ -340,6 +342,8 @@ export default {
             // Also trigger screenshot refresh here
             // eslint-disable-next-line vue/no-side-effects-in-computed-properties
             this.cacheTime = Date.now();
+            // eslint-disable-next-line vue/no-side-effects-in-computed-properties
+            this.timeRemaining = this.monitor.interval;
 
             if (this.monitor.id in this.$root.lastHeartbeatList && this.$root.lastHeartbeatList[this.monitor.id]) {
                 return this.$root.lastHeartbeatList[this.monitor.id];
@@ -399,7 +403,13 @@ export default {
 
         screenshotURL() {
             return getResBaseURL() + this.monitor.screenshot + "?time=" + this.cacheTime;
-        }
+        },
+
+        formattedTime() {
+            const minutes = Math.floor(this.timeRemaining / 60);
+            const seconds = this.timeRemaining % 60;
+            return `${minutes}:${seconds.toString().padStart(2, '0')}`;
+        },
     },
 
     watch: {
@@ -419,7 +429,14 @@ export default {
             this.loadPushExample();
         },
     },
-
+    created() {
+        if (this.lastHeartBeat.end_time) {
+            const lastpingtime = dayjs().utc().diff(dayjs.utc(this.lastHeartBeat.end_time), "seconds")
+            this.timeRemaining = this.monitor.interval - lastpingtime;
+        } else {
+            this.timeRemaining = this.monitor.interval;
+        }
+    },
     mounted() {
         this.getImportantHeartbeatListLength();
 
@@ -431,10 +448,17 @@ export default {
             }
             this.loadPushExample();
         }
+
+        this.interval = setInterval(() => {
+            if (this.timeRemaining > 1) {
+                this.timeRemaining--;
+            }
+        }, 1000);
     },
 
     beforeUnmount() {
         this.$root.emitter.off("newImportantHeartbeat", this.onNewImportantHeartbeat);
+        clearInterval(this.interval);
     },
 
     methods: {
@@ -464,6 +488,7 @@ export default {
             this.$root.getSocket().emit("resumeMonitor", this.monitor.id, (res) => {
                 this.$root.toastRes(res);
             });
+            this.timeRemaining = this.monitor.interval;
         },
 
         /**

From e90965a212330e7eadcd60706701dc42287f9040 Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Sat, 12 Oct 2024 01:08:36 +0530
Subject: [PATCH 16/20] better formatting

---
 src/pages/Details.vue | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/src/pages/Details.vue b/src/pages/Details.vue
index 50f4ec0dd..eb5b3d306 100644
--- a/src/pages/Details.vue
+++ b/src/pages/Details.vue
@@ -406,9 +406,24 @@ export default {
         },
 
         formattedTime() {
-            const minutes = Math.floor(this.timeRemaining / 60);
+            const days = Math.floor(this.timeRemaining / 86400);
+            const hours = Math.floor((this.timeRemaining % 86400) / 3600);
+            const minutes = Math.floor((this.timeRemaining % 3600) / 60);
             const seconds = this.timeRemaining % 60;
-            return `${minutes}:${seconds.toString().padStart(2, '0')}`;
+
+            let formattedTime = '';
+            if (days > 0) {
+                formattedTime += `${days}:`;
+            }
+            if (hours > 0 || days > 0) {
+                formattedTime += `${hours}:`;
+            }
+            if (minutes > 0 || hours > 0 || days > 0) {
+                formattedTime += `${minutes}:`;
+            }
+            formattedTime += `${seconds}`;
+
+            return formattedTime.trim();
         },
     },
 

From d7f9a9b47172d368f99576fc9b4cfab77bc6b233 Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Sat, 12 Oct 2024 01:11:07 +0530
Subject: [PATCH 17/20] lint fixes

---
 src/pages/Details.vue | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/pages/Details.vue b/src/pages/Details.vue
index eb5b3d306..27feb1ac4 100644
--- a/src/pages/Details.vue
+++ b/src/pages/Details.vue
@@ -1,3 +1,4 @@
+<!-- eslint-disable linebreak-style -->
 <template>
     <transition name="slide-fade" appear>
         <div v-if="monitor">
@@ -411,7 +412,7 @@ export default {
             const minutes = Math.floor((this.timeRemaining % 3600) / 60);
             const seconds = this.timeRemaining % 60;
 
-            let formattedTime = '';
+            let formattedTime = "";
             if (days > 0) {
                 formattedTime += `${days}:`;
             }
@@ -446,7 +447,7 @@ export default {
     },
     created() {
         if (this.lastHeartBeat.end_time) {
-            const lastpingtime = dayjs().utc().diff(dayjs.utc(this.lastHeartBeat.end_time), "seconds")
+            const lastpingtime = dayjs().utc().diff(dayjs.utc(this.lastHeartBeat.end_time), "seconds");
             this.timeRemaining = this.monitor.interval - lastpingtime;
         } else {
             this.timeRemaining = this.monitor.interval;

From 5ce3f0615fb2668478523185c00a5e518c8e22bf Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Sat, 12 Oct 2024 08:42:45 +0530
Subject: [PATCH 18/20] Component breakdown

---
 src/components/NextPingTimer.vue | 52 ++++++++++++++++++++++++++++++++
 src/pages/Details.vue            | 29 ++++--------------
 2 files changed, 58 insertions(+), 23 deletions(-)
 create mode 100644 src/components/NextPingTimer.vue

diff --git a/src/components/NextPingTimer.vue b/src/components/NextPingTimer.vue
new file mode 100644
index 000000000..e4f707ce6
--- /dev/null
+++ b/src/components/NextPingTimer.vue
@@ -0,0 +1,52 @@
+<template>
+    <span class="word">&nbsp;({{ $t("nextCheckIn") }}: {{ formattedTime }})</span>
+</template>
+
+<script>
+
+export default {
+    props: {
+        /** Time remaining in seconds */
+        timeRemaining: {
+            type: Number,
+            required: true,
+        },
+    },
+    computed: {
+        /**
+         * Formatted time remaining
+         * @returns {string} Formatted time
+         */
+        formattedTime() {
+            const days = Math.floor(this.timeRemaining / 86400);
+            const hours = Math.floor((this.timeRemaining % 86400) / 3600);
+            const minutes = Math.floor((this.timeRemaining % 3600) / 60);
+            const seconds = this.timeRemaining % 60;
+
+            let formattedTime = "";
+            if (seconds >= 0) {
+                formattedTime = seconds > 1 ? `${seconds}secs` : `${seconds}sec`;
+            }
+            if (minutes > 0) {
+                formattedTime = minutes > 1 ? `${minutes}mins` : `${minutes}min`;
+            }
+            if (hours > 0) {
+                formattedTime = hours > 1 ? `${hours}hrs` : `${hours}hr`;
+            }
+            if (days > 0) {
+                formattedTime = days > 1 ? `${days}days` : `${days}day`;
+            }
+
+            return formattedTime.trim();
+        },
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "../assets/vars.scss";
+.word {
+    color: $secondary-text;
+    font-size: 12px;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/Details.vue b/src/pages/Details.vue
index 27feb1ac4..c712fb066 100644
--- a/src/pages/Details.vue
+++ b/src/pages/Details.vue
@@ -1,4 +1,3 @@
-<!-- eslint-disable linebreak-style -->
 <template>
     <transition name="slide-fade" appear>
         <div v-if="monitor">
@@ -77,7 +76,10 @@
                 <div class="row">
                     <div class="col-md-8">
                         <HeartbeatBar :monitor-id="monitor.id" />
-                        <div><span v-if="monitor.active" class="mr-2">Next in {{ formattedTime }}&nbsp;</span><span class="word">({{ $t("checkEverySecond", [ monitor.interval ]) }})</span></div>
+                        <div>
+                            <span class="word">{{ $t("checkEverySecond", [ monitor.interval ]) }}</span>
+                            <span class="word"><NextPingTimer :timeRemaining="timeRemaining" /></span>
+                        </div>
                     </div>
                     <div class="col-md-4 text-center">
                         <span class="badge rounded-pill" :class=" 'bg-' + status.color " style="font-size: 30px;" data-testid="monitor-status">{{ status.text }}</span>
@@ -276,6 +278,7 @@ import { useToast } from "vue-toastification";
 const toast = useToast();
 import Confirm from "../components/Confirm.vue";
 import HeartbeatBar from "../components/HeartbeatBar.vue";
+import NextPingTimer from "../components/NextPingTimer.vue";
 import Status from "../components/Status.vue";
 import Datetime from "../components/Datetime.vue";
 import CountUp from "../components/CountUp.vue";
@@ -302,6 +305,7 @@ export default {
         CountUp,
         Datetime,
         HeartbeatBar,
+        NextPingTimer,
         Confirm,
         Status,
         Pagination,
@@ -405,27 +409,6 @@ export default {
         screenshotURL() {
             return getResBaseURL() + this.monitor.screenshot + "?time=" + this.cacheTime;
         },
-
-        formattedTime() {
-            const days = Math.floor(this.timeRemaining / 86400);
-            const hours = Math.floor((this.timeRemaining % 86400) / 3600);
-            const minutes = Math.floor((this.timeRemaining % 3600) / 60);
-            const seconds = this.timeRemaining % 60;
-
-            let formattedTime = "";
-            if (days > 0) {
-                formattedTime += `${days}:`;
-            }
-            if (hours > 0 || days > 0) {
-                formattedTime += `${hours}:`;
-            }
-            if (minutes > 0 || hours > 0 || days > 0) {
-                formattedTime += `${minutes}:`;
-            }
-            formattedTime += `${seconds}`;
-
-            return formattedTime.trim();
-        },
     },
 
     watch: {

From a4ab9caa4369a7bc22bc652a8733c92e95203523 Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Sat, 12 Oct 2024 08:50:36 +0530
Subject: [PATCH 19/20] FIx 1

---
 src/components/NextPingTimer.vue | 2 +-
 src/lang/en.json                 | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/components/NextPingTimer.vue b/src/components/NextPingTimer.vue
index e4f707ce6..c87243af7 100644
--- a/src/components/NextPingTimer.vue
+++ b/src/components/NextPingTimer.vue
@@ -49,4 +49,4 @@ export default {
     color: $secondary-text;
     font-size: 12px;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/src/lang/en.json b/src/lang/en.json
index c07e06fab..a5b5393f5 100644
--- a/src/lang/en.json
+++ b/src/lang/en.json
@@ -1051,5 +1051,6 @@
     "From":"From",
     "Can be found on:": "Can be found on: {0}",
     "The phone number of the recipient in E.164 format.": "The phone number of the recipient in E.164 format.",
-    "Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.":"Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies."
+    "Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.":"Either a text sender ID or a phone number in E.164 format if you want to be able to receive replies.",
+    "nextCheckIn": "Next in "
 }

From f65e5e5848839cdd6fc9273b978e6ec8d05dd3c2 Mon Sep 17 00:00:00 2001
From: mohit-nagaraj <mohitnagaraj20@gmail.com>
Date: Sat, 12 Oct 2024 13:16:30 +0530
Subject: [PATCH 20/20] Update NextPingTimer.vue

---
 src/components/NextPingTimer.vue | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/components/NextPingTimer.vue b/src/components/NextPingTimer.vue
index c87243af7..8bb30f0a4 100644
--- a/src/components/NextPingTimer.vue
+++ b/src/components/NextPingTimer.vue
@@ -28,13 +28,13 @@ export default {
                 formattedTime = seconds > 1 ? `${seconds}secs` : `${seconds}sec`;
             }
             if (minutes > 0) {
-                formattedTime = minutes > 1 ? `${minutes}mins` : `${minutes}min`;
+                formattedTime = minutes > 1 ? `~ ${minutes}mins` : `~ ${minutes}min`;
             }
             if (hours > 0) {
-                formattedTime = hours > 1 ? `${hours}hrs` : `${hours}hr`;
+                formattedTime = hours > 1 ? `~ ${hours}hrs` : `~ ${hours}hr`;
             }
             if (days > 0) {
-                formattedTime = days > 1 ? `${days}days` : `${days}day`;
+                formattedTime = days > 1 ? `~ ${days}days` : `~ ${days}day`;
             }
 
             return formattedTime.trim();
@@ -45,8 +45,10 @@ export default {
 
 <style lang="scss" scoped>
 @import "../assets/vars.scss";
+
 .word {
     color: $secondary-text;
     font-size: 12px;
 }
+
 </style>