FEATURE: allow iPad users to specify they have a physical keyboard

FEATURE: allow iPad users to specify they have a physical keyboard

Sadly there is no clean way of detecting a keyboard is connected to an iPad

If the keyboard is connected we want to disable all the touch related hacks on iOS

This allows iPad users to specify they have a keyboard connected. Setting is per device.

diff --git a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6
index 8eec21b..16f1c8b 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6
@@ -10,6 +10,7 @@ import {
   setLocalTheme
 } from "discourse/lib/theme-selector";
 import { popupAjaxError } from "discourse/lib/ajax-error";
+import { safariHacksDisabled } from "discourse/lib/utilities";
 
 const USER_HOMES = {
   1: "latest",
@@ -47,6 +48,19 @@ export default Ember.Controller.extend(PreferencesTabController, {
   preferencesController: Ember.inject.controller("preferences"),
 
   @computed()
+  isiPad() {
+    return (
+      navigator.userAgent.match(/iPad/g) &&
+      !navigator.userAgent.match(/Trident/g)
+    );
+  },
+
+  @computed()
+  disableSafariHacks() {
+    return safariHacksDisabled();
+  },
+
+  @computed()
   availableLocales() {
     return JSON.parse(this.siteSettings.available_locales);
   },
@@ -137,6 +151,16 @@ export default Ember.Controller.extend(PreferencesTabController, {
           }
 
           this.homeChanged();
+
+          if (this.get("isiPad")) {
+            if (safariHacksDisabled() !== this.get("disableSafariHacks")) {
+              Discourse.set("assetVersion", "forceRefresh");
+            }
+            localStorage.setItem(
+              "safari-hacks-disabled",
+              this.get("disableSafariHacks").toString()
+            );
+          }
         })
         .catch(popupAjaxError);
     },
diff --git a/app/assets/javascripts/discourse/lib/safari-hacks.js.es6 b/app/assets/javascripts/discourse/lib/safari-hacks.js.es6
index 8c7c9df..026826c 100644
--- a/app/assets/javascripts/discourse/lib/safari-hacks.js.es6
+++ b/app/assets/javascripts/discourse/lib/safari-hacks.js.es6
@@ -1,4 +1,4 @@
-import { isAppleDevice } from "discourse/lib/utilities";
+import { isAppleDevice, safariHacksDisabled } from "discourse/lib/utilities";
 
 // we can't tell what the actual visible window height is
 // because we cannot account for the height of the mobile keyboard
@@ -65,7 +65,7 @@ export function isWorkaroundActive() {
 
 // per http://stackoverflow.com/questions/29001977/safari-in-ios8-is-scrolling-screen-when-fixed-elements-get-focus/29064810
 function positioningWorkaround($fixedElement) {
-  if (!isAppleDevice()) {
+  if (!isAppleDevice() || safariHacksDisabled()) {
     return;
   }
 
diff --git a/app/assets/javascripts/discourse/lib/utilities.js.es6 b/app/assets/javascripts/discourse/lib/utilities.js.es6
index 3ce16c3..23e0248 100644
--- a/app/assets/javascripts/discourse/lib/utilities.js.es6
+++ b/app/assets/javascripts/discourse/lib/utilities.js.es6
@@ -550,6 +550,15 @@ export function isAppleDevice() {
   );
 }
 
+export function safariHacksDisabled() {
+  let pref = localStorage.getItem("safari-hacks-disabled");
+  let result = false;
+  if (pref !== null) {
+    result = pref === "true";
+  }
+  return result;
+}
+
 const toArray = items => {
   items = items || [];
 
diff --git a/app/assets/javascripts/discourse/templates/preferences/interface.hbs b/app/assets/javascripts/discourse/templates/preferences/interface.hbs
index a24d7e8..a74f42b 100644
--- a/app/assets/javascripts/discourse/templates/preferences/interface.hbs
+++ b/app/assets/javascripts/discourse/templates/preferences/interface.hbs
@@ -55,6 +55,9 @@
     {{preference-checkbox labelKey="user.automatically_unpin_topics" checked=model.user_option.automatically_unpin_topics}}
   {{/if}}
   {{preference-checkbox labelKey="user.hide_profile_and_presence" checked=model.user_option.hide_profile_and_presence}}
+  {{#if isiPad}}
+    {{preference-checkbox labelKey="user.enable_physical_keyboard" checked=disableSafariHacks}}
+  {{/if}}
 </div>
 
 {{plugin-outlet name="user-preferences-interface" args=(hash model=model save=(action "save"))}}
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index ffc3400..0074c82 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -915,6 +915,7 @@ en:
       website: "Web Site"
       email_settings: "Email"
       hide_profile_and_presence: "Hide my public profile and presence features"
+      enable_physical_keyboard: "Enable physical keyboard support on iPad"
 
       text_size:
         title: "Text Size"

GitHub sha: 0b86a99c

1 Like