From ee19672fd3eef8cda5668c5c8f24443bb720214d Mon Sep 17 00:00:00 2001
From: Hangzhi Yu <hangzhi@protonmail.com>
Date: Fri, 13 Jan 2023 23:01:36 +0100
Subject: [PATCH] Add basic offline check and indicator

---
 aleksis/core/assets/App.vue          | 28 ++++++++++++++++++++++++++--
 aleksis/core/assets/app.js           |  3 ++-
 aleksis/core/assets/messages/en.json |  3 ++-
 aleksis/core/assets/ping.graphql     |  3 +++
 4 files changed, 33 insertions(+), 4 deletions(-)
 create mode 100644 aleksis/core/assets/ping.graphql

diff --git a/aleksis/core/assets/App.vue b/aleksis/core/assets/App.vue
index 026e5c418..19c3ad0b9 100644
--- a/aleksis/core/assets/App.vue
+++ b/aleksis/core/assets/App.vue
@@ -185,8 +185,13 @@
       </v-app-bar>
       <v-main>
         <v-container>
-          <broadcast-channel-notification channel-name="cache-or-not" />
-          <broadcast-channel-notification channel-name="offline-fallback" />
+          <broadcast-channel-notification channel-name="cache-or-not"/>
+
+          <message-box
+              type="warning"
+              v-if="$root.offline"
+          >{{ $t("network_errors.offline_notification") }}
+          </message-box>
 
           <message-box
             type="error"
@@ -361,6 +366,7 @@ export default {
       sideNavMenu: null,
       accountMenu: null,
       snackbarItems: null,
+      ping: null,
     };
   },
   methods: {
@@ -500,6 +506,24 @@ export default {
       },
       deep: true,
     },
+    ping: function (ping) {
+      if (ping === "pong") {
+        this.$apollo.queries.ping.stopPolling();
+        this.$apollo.queries.whoAmI.startPolling(10000);
+        this.$apollo.queries.snackbarItems.startPolling(1000);
+        this.$apollo.queries.messages.startPolling(1000);
+        this.$root.offline = false;
+      }
+    },
+    "$root.offline": function (offline) {
+      if (offline) {
+        this.ping = null;
+        this.$apollo.queries.ping.startPolling(1000);
+        this.$apollo.queries.whoAmI.stopPolling();
+        this.$apollo.queries.snackbarItems.stopPolling();
+        this.$apollo.queries.messages.stopPolling();
+      }
+    },
   },
   mounted() {
     this.$router.onReady(this.getPermissionNames);
diff --git a/aleksis/core/assets/app.js b/aleksis/core/assets/app.js
index 01c0b672d..14d3696bf 100644
--- a/aleksis/core/assets/app.js
+++ b/aleksis/core/assets/app.js
@@ -128,7 +128,7 @@ const errorLink = onError(({ graphQLErrors, networkError }) => {
   if (graphQLErrors) addErrorSnackbarItem("graphql.snackbar_error_message");
 
   if (networkError)
-    addErrorSnackbarItem("network_errors.snackbar_error_message");
+    app.offline = true;
 });
 
 const httpLink = new HttpLink({
@@ -193,6 +193,7 @@ const app = new Vue({
   data: () => ({
     showCacheAlert: false,
     contentLoading: false,
+    offline: false,
   }),
   router,
   i18n,
diff --git a/aleksis/core/assets/messages/en.json b/aleksis/core/assets/messages/en.json
index b2679b64a..78cc0ab99 100644
--- a/aleksis/core/assets/messages/en.json
+++ b/aleksis/core/assets/messages/en.json
@@ -181,7 +181,8 @@
     "error_404": "404",
     "page_not_found": "The requested page or resource could not be found.",
     "take_me_back": "Take me back",
-    "snackbar_error_message": "A network error occurred. Please try again."
+    "snackbar_error_message": "A network error occurred. Please try again.",
+    "offline_notification": "You are offline. Some features may not work and some data may not be up to date."
   },
   "service_worker": {
     "new_version_available": "A new version of the app is available",
diff --git a/aleksis/core/assets/ping.graphql b/aleksis/core/assets/ping.graphql
new file mode 100644
index 000000000..1a13edeb7
--- /dev/null
+++ b/aleksis/core/assets/ping.graphql
@@ -0,0 +1,3 @@
+{
+  ping
+}
-- 
GitLab