UI: Footer nav fixes

UI: Footer nav fixes

  • moves footer nav to the header on iPads
  • disables scrolling events for iPads
  • removes footer nav entirely on Chrome PWAs
  • toggles DiscourseHub iOS app status bar styling (dark/light) when opening/closing lightboxes and modals
diff --git a/app/assets/javascripts/discourse/components/d-modal-body.js.es6 b/app/assets/javascripts/discourse/components/d-modal-body.js.es6
index a498875..f908682 100644
--- a/app/assets/javascripts/discourse/components/d-modal-body.js.es6
+++ b/app/assets/javascripts/discourse/components/d-modal-body.js.es6
@@ -22,6 +22,7 @@ export default Ember.Component.extend({
     this._super(...arguments);
     this.appEvents.off("modal-body:flash", this, "_flash");
     this.appEvents.off("modal-body:clearFlash", this, "_clearFlash");
+    this.appEvents.trigger("modal:body-dismissed");
   },
 
   _afterFirstRender() {
diff --git a/app/assets/javascripts/discourse/components/footer-nav.js.es6 b/app/assets/javascripts/discourse/components/footer-nav.js.es6
index 56eecf2..0cbf317 100644
--- a/app/assets/javascripts/discourse/components/footer-nav.js.es6
+++ b/app/assets/javascripts/discourse/components/footer-nav.js.es6
@@ -2,6 +2,8 @@ import MountWidget from "discourse/components/mount-widget";
 import MobileScrollDirection from "discourse/mixins/mobile-scroll-direction";
 import Scrolling from "discourse/mixins/scrolling";
 import { observes } from "ember-addons/ember-computed-decorators";
+import { isiPad } from "discourse/lib/utilities";
+import { isAppWebview, postRNWebviewMessage } from "discourse/lib/utilities";
 
 const MOBILE_SCROLL_DIRECTION_CHECK_THROTTLE = 150;
 
@@ -28,22 +30,40 @@ const FooterNavComponent = MountWidget.extend(
 
     didInsertElement() {
       this._super(...arguments);
-      this.bindScrolling({ name: "footer-nav" });
-      $(window).on("resize.footer-nav-on-scroll", () => this.scrolled());
       this.appEvents.on("page:changed", this, "_routeChanged");
-      this.appEvents.on("composer:opened", this, "_composerOpened");
-      this.appEvents.on("composer:closed", this, "_composerClosed");
-      $("body").addClass("with-footer-nav");
+
+      if (isAppWebview()) {
+        this.appEvents.on("modal:body-shown", this, "_modalOn");
+        this.appEvents.on("modal:body-dismissed", this, "_modalOff");
+      }
+
+      if (isiPad()) {
+        $("body").addClass("footer-nav-ipad");
+      } else {
+        this.bindScrolling({ name: "footer-nav" });
+        $(window).on("resize.footer-nav-on-scroll", () => this.scrolled());
+        this.appEvents.on("composer:opened", this, "_composerOpened");
+        this.appEvents.on("composer:closed", this, "_composerClosed");
+      }
     },
 
     willDestroyElement() {
       this._super(...arguments);
-      this.unbindScrolling("footer-nav");
-      $(window).unbind("resize.footer-nav-on-scroll");
       this.appEvents.off("page:changed", this, "_routeChanged");
-      this.appEvents.off("composer:opened", this, "_composerOpened");
-      this.appEvents.off("composer:closed", this, "_composerClosed");
-      $("body").removeClass("with-footer-nav");
+
+      if (isAppWebview()) {
+        this.appEvents.off("modal:body-shown", this, "_modalOn");
+        this.appEvents.off("modal:body-removed", this, "_modalOff");
+      }
+
+      if (isiPad()) {
+        $("body").removeClass("footer-nav-ipad");
+      } else {
+        this.unbindScrolling("footer-nav");
+        $(window).unbind("resize.footer-nav-on-scroll");
+        this.appEvents.off("composer:opened", this, "_composerOpened");
+        this.appEvents.off("composer:closed", this, "_composerClosed");
+      }
     },
 
     // The user has scrolled the window, or it is finished rendering and ready for processing.
@@ -105,6 +125,17 @@ const FooterNavComponent = MountWidget.extend(
       this.set("scrollEventDisabled", false);
     },
 
+    _modalOn() {
+      postRNWebviewMessage(
+        "headerBg",
+        $(".modal-backdrop").css("background-color")
+      );
+    },
+
+    _modalOff() {
+      postRNWebviewMessage("headerBg", $(".d-header").css("background-color"));
+    },
+
     goBack() {
       this.set("currentRouteIndex", this.get("currentRouteIndex") - 1);
       this.backForwardClicked = true;
diff --git a/app/assets/javascripts/discourse/controllers/application.js.es6 b/app/assets/javascripts/discourse/controllers/application.js.es6
index 12459fd..ce23c50 100644
--- a/app/assets/javascripts/discourse/controllers/application.js.es6
+++ b/app/assets/javascripts/discourse/controllers/application.js.es6
@@ -1,5 +1,5 @@
 import computed from "ember-addons/ember-computed-decorators";
-import { isAppWebview, isiOSPWA, isChromePWA } from "discourse/lib/utilities";
+import { isAppWebview, isiOSPWA } from "discourse/lib/utilities";
 
 export default Ember.Controller.extend({
   showTop: true,
@@ -21,10 +21,6 @@ export default Ember.Controller.extend({
 
   @computed
   showFooterNav() {
-    return (
-      isAppWebview() ||
-      isiOSPWA() ||
-      (!this.site.isMobileDevice && isChromePWA())
-    );
+    return isAppWebview() || isiOSPWA();
   }
 });
diff --git a/app/assets/javascripts/discourse/initializers/mobile.js.es6 b/app/assets/javascripts/discourse/initializers/mobile.js.es6
index fa38f88..a536398 100644
--- a/app/assets/javascripts/discourse/initializers/mobile.js.es6
+++ b/app/assets/javascripts/discourse/initializers/mobile.js.es6
@@ -1,5 +1,6 @@
 import Mobile from "discourse/lib/mobile";
 import { setResolverOption } from "discourse-common/resolver";
+import { isAppWebview, postRNWebviewMessage } from "discourse/lib/utilities";
 
 // Initializes the `Mobile` helper object.
 export default {
@@ -15,11 +16,11 @@ export default {
 
     setResolverOption("mobileView", Mobile.mobileView);
 
-    if (window.ReactNativeWebView) {
+    if (isAppWebview()) {
       Ember.run.later(() => {
-        let headerBg = $(".d-header").css("background-color");
-        window.ReactNativeWebView.postMessage(
-          JSON.stringify({ headerBg: headerBg })
+        postRNWebviewMessage(
+          "headerBg",
+          $(".d-header").css("background-color")
         );
       }, 500);
     }
diff --git a/app/assets/javascripts/discourse/lib/lightbox.js.es6 b/app/assets/javascripts/discourse/lib/lightbox.js.es6
index 77c675e..ee09275 100644
--- a/app/assets/javascripts/discourse/lib/lightbox.js.es6
+++ b/app/assets/javascripts/discourse/lib/lightbox.js.es6
@@ -1,6 +1,7 @@
 import loadScript from "discourse/lib/load-script";
 import { escapeExpression } from "discourse/lib/utilities";
 import { renderIcon } from "discourse-common/lib/icon-library";
+import { isAppWebview, postRNWebviewMessage } from "discourse/lib/utilities";
 
 export default function($elem) {
   if (!$elem) {
@@ -35,10 +36,23 @@ export default function($elem) {
                 wrap.hasClass("mfp-force-scrollbars") ? "none" : maxHeight
               );
             });
+
+            if (isAppWebview()) {
+              postRNWebviewMessage(
+                "headerBg",
+                $(".mfp-bg").css("background-color")
+              );
+            }
           },
           beforeClose() {
             this.wrap.off("click.pinhandler");
             this.wrap.removeClass("mfp-force-scrollbars");
+            if (isAppWebview()) {
+              postRNWebviewMessage(
+                "headerBg",
+                $(".d-header").css("background-color")
+              );
+            }
           }
         },
 
diff --git a/app/assets/javascripts/discourse/lib/utilities.js.es6 b/app/assets/javascripts/discourse/lib/utilities.js.es6
index 06f6cc4..4d5240b 100644
--- a/app/assets/javascripts/discourse/lib/utilities.js.es6
+++ b/app/assets/javascripts/discourse/lib/utilities.js.es6
@@ -654,12 +654,10 @@ export function isAppWebview() {
   return window.ReactNativeWebView !== undefined;
 }
 
-export function isChromePWA() {
-  // Watch out: this doesn't distinguish between mobile or desktop PWAs
-  return (
-    window.matchMedia("(display-mode: standalone)").matches &&
-    navigator.userAgent.match(/(Chrome)/g)
-  );
+export function postRNWebviewMessage(prop, value) {
+  if (window.ReactNativeWebView !== undefined) {

[... diff too long, it was truncated ...]

GitHub sha: de10bd7f