Skip to content

Commit

Permalink
added: add-to-homescreen dialog for some mobile browsers,
Browse files Browse the repository at this point in the history
  • Loading branch information
MartijnR committed Jan 1, 2016
1 parent 0c160d1 commit c7ed92a
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 20 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http:https://semver.org/).

[Unreleased]
[1.22.0] - 2016-01-01
---------------------
##### Added
- Export functionality.
- Add-to-homescreen guidance for iOS/Safari, Android/Chrome and Android/Firefox.

##### Changed
- Links are underlined.
Expand Down
28 changes: 22 additions & 6 deletions app/views/styles/component/_form_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,15 @@ $offline-color: #d15200;
}
}

.form-header__button--homescreen {
position: fixed;
top: 1px;
right: 6px;
.icon {
font-size: 25px;
}
}

@media screen and (max-width: $main-breakpoint + 100px) {
body {
.main {
Expand Down Expand Up @@ -191,6 +200,10 @@ $offline-color: #d15200;
.or .form-logo {
margin-top: 45px;
}
.form-header__button--homescreen {
position: absolute;
top: 73px;
}
}

@media screen and (max-width: $main-breakpoint) {
Expand All @@ -199,6 +212,15 @@ $offline-color: #d15200;
background-color: rgb(245, 245, 245);
}
}
.form-header__button--print {
display: none;
~ .form-language-selector {
border-right: none;
}
}
.form-header__button--homescreen {
top: -2px;
}
}

@media screen and (max-width: 600px) {
Expand All @@ -211,12 +233,6 @@ $offline-color: #d15200;
.form-language-selector {
padding-right: 0;
}
.form-header__button--print {
display: none;
~ .form-language-selector {
border-right: none;
}
}
}

@media screen and (max-width: 430px) {
Expand Down
12 changes: 10 additions & 2 deletions app/views/styles/component/_icons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@
@extend .fa-pencil;
}

.icon-link {
@extend .fa-link;
.icon-bookmark-o {
@extend .fa-bookmark-o;
}

.icon-ellipsis-v {
@extend .fa-ellipsis-v;
}

.icon-star-o {
@extend .fa-star-o;
}
4 changes: 4 additions & 0 deletions app/views/styles/component/_iframe.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
border-radius: 0;
border: none;
}
.form-header__button--homescreen {
display: none;
}
}

// TODO: remove?
.edit .paper .branding {
display: none;
}
Expand Down
23 changes: 23 additions & 0 deletions app/views/styles/component/_modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,26 @@
}
}
}

.ios-safari {
$width: 25px;
$height: 30px;
display: inline-block;
width: $width;
height: $height;
margin-bottom: -3px;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADYAAAA/CAYAAACrSjsVAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACw2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDxwaG90b3Nob3A6RGF0ZUNyZWF0ZWQ+MjAxNS0xMi0yNFQwOToxODozMTwvcGhvdG9zaG9wOkRhdGVDcmVhdGVkPgogICAgICAgICA8ZXhpZjpVc2VyQ29tbWVudD4KICAgICAgICAgICAgPHJkZjpBbHQ+CiAgICAgICAgICAgICAgIDxyZGY6bGkgeG1sOmxhbmc9IngtZGVmYXVsdCI+U2NyZWVuc2hvdDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpBbHQ+CiAgICAgICAgIDwvZXhpZjpVc2VyQ29tbWVudD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CqO4YmMAAAIkSURBVGgF7ZrPSsNAEMZnTaOCvogeFAQv2h7EiwcREU+CJ0+eBBFEoSK1tIhePKigT+ADeNfWgx68+SjaRtKo2dJtlKKZltkhjbOlJCST+eab32ZJ/6harfYJKRwDKfTUtCTG+o0sG7Hygwv6zTUyHELaUOkuktrL+tZlIzVLUsWKC8eVSMYYtG0uA8qSozBt8f6nKaPUNpezR25Ahc5svL6bys81jCcw+9pcuepa0dZ+rCweh2HRZvoV5n3YzUbG9L4+poc2V6pG07TtnmCH3Jg2ddoq9mTBh+2ZoKNMfUyf08OWOdJ2GVMqbNfFog/rk52mjMvN6QAGHYCt22jF3M9FZE1cr1syYmePTpOUNnW9/LcpU+zGVACXSz7oazS5q+fQKdEgI7Y2EcDNiwM7sw1YGftAl6epumEV508OrI7/ThidsBWo6vU6y9P96NFwU/I173VbY0/xZFOxJ3WLF4kxi821kjq1xGJXRXPTd9tW7CJhK///JWZIYQmYeOy227xYwqklJsawUyspcUIsKSSwdQgxbKeSEifEkkICW4cQw3YqKXFCLCkksHUIMWynkhKXUQr3cws2Ls4YV57YrwbiCsWefzt4x4aSxMk9RtJGxiRCjLHZJFJCjKSNjEmEGGOzSaSEGEkbGZMIMcZmk0gJMZI2MiYRYozNJpFCf9AcKQyRCHIlSe1UVJ7nsfzliIuU0UktMTFmEPfLVoj1CylT5xd6HHOR9k4uUAAAAABJRU5ErkJggg==);
background-size: $width $height;
background-repeat: no-repeat;
}

.android-chrome, .android-firefox-1 {
@extend .icon;
@extend .icon-ellipsis-v;
padding: 0 5px;
}

.android-firefox-2 {
@extend .icon;
@extend .icon-star-o;
}
2 changes: 2 additions & 0 deletions app/views/surveys/component/_form-header.jade
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ header.form-header
img(src="#{logo.source}", alt="brand logo")
button.form-header__button--print(onclick="return false;").hide
span.form-language-selector.hide: span= t('form.chooseLanguage')
button.form-header__button--homescreen.btn-icon-only.hide(type="button")
i.icon.icon-bookmark-o
18 changes: 18 additions & 0 deletions locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,24 @@
"flushdb": "Clear Storage"
},
"alert": {
"addtohomescreen": {
"androidchrome": {
"msg": "To add this form to your Home screen, click the browser settings icon __image1__ and select: 'Add to Home screen'."
},
"androidfirefox": {
"msg": [
"To add this form to your Homescreen:",
"1. Add this page to your Firefox bookmarks by clicking the settings icon __image1__ and then the star icon __image2__.",
"2. Open your bookmarks by opening a new page and clicking the Bookmarks tab.",
"3. Click-and-hold your form until a pop-up menu appears.",
"4. Select 'Add to Home Screen'."
]
},
"heading": "Add to Home Screen",
"iossafari": {
"msg": "To add this form to your Home screen, click the share icon __image1__ in the top right of your browser, and select: '+ Add to Home Screen'."
}
},
"appupdated": {
"heading": "App Updated!",
"msg": "A new version of this application has been downloaded. Refresh this page to load the updated version."
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "enketo-express",
"description": "A simplified version of Enketo Smart Paper that requires a constant connection to the server.",
"homepage": "",
"version": "1.21.2",
"version": "1.22.0",
"main": "./app.js",
"repository": {
"type": "git",
Expand Down
41 changes: 41 additions & 0 deletions public/js/src/module/gui.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ var support = require( 'enketo-core/src/js/support' );
var settings = require( './settings' );
var printForm = require( 'enketo-core/src/js/print' );
var t = require( './translator' );
var sniffer = require( './sniffer' );
var dialog = require( './vex.dialog.custom' );
var $ = require( 'jquery' );
require( './plugin' );

var pages;
var homeScreenGuidance;
var updateStatus;
var feedbackBar;

Expand Down Expand Up @@ -83,6 +85,10 @@ function setEventHandlers() {
return ( !href || href === '#' ) ? false : true;
} );

if ( _getHomeScreenGuidance() ) {
$( '.form-header__button--homescreen' ).removeClass( 'hide' ).on( 'click', alertHomeScreenGuidance );
}

$doc.on( 'xpatherror', function( ev, error ) {
var email = settings[ 'supportEmail' ],
link = '<a href="mailto:' + email + '?subject=xpath errors for: ' + location.href + '&body=' + error + '" target="_blank" >' + email + '</a>';
Expand Down Expand Up @@ -337,6 +343,41 @@ function alertLoadErrors( loadErrors, advice ) {
);
}

function alertHomeScreenGuidance() {
alert( _getHomeScreenGuidance(), t( 'alert.addtohomescreen.heading' ), 'normal' );
}

function _getHomeScreenGuidance() {
var imageClass1;
var imageClass2;
var guidanceKey;
var browser = sniffer.browser;
var os = sniffer.os;

if ( homeScreenGuidance ) {
// keep calm
} else if ( os.isIos() && browser.isSafari() ) {
imageClass1 = 'ios-safari';
homeScreenGuidance = t( 'alert.addtohomescreen.iossafari.msg', _getHomeScreenGuidanceObj( imageClass1 ) );
} else if ( os.isAndroid() && browser.isChrome() ) {
imageClass1 = 'android-chrome';
homeScreenGuidance = t( 'alert.addtohomescreen.androidchrome.msg', _getHomeScreenGuidanceObj( imageClass1 ) );
} else if ( os.isAndroid() && browser.isFirefox() ) {
imageClass1 = 'android-firefox-1';
imageClass2 = 'android-firefox-2';
homeScreenGuidance = t( 'alert.addtohomescreen.androidfirefox.msg', _getHomeScreenGuidanceObj( imageClass1, imageClass2 ) );
}

return homeScreenGuidance;
}

function _getHomeScreenGuidanceObj( imageClass1, imageClass2 ) {
return {
image1: ( imageClass1 ) ? '<span class="' + imageClass1 + '"/>' : '',
image2: ( imageClass2 ) ? '<span class="' + imageClass2 + '"/>' : ''
};
}

/**
* Prompts for print settings
*
Expand Down
30 changes: 21 additions & 9 deletions public/js/src/module/sniffer.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
'use strict';

var browser;

/**
* It is a sad state of affairs that we need this.
*/
var os;
var ua = navigator.userAgent;
var platform = navigator.platform;

browser = {
isChrome: function() {
var matchedChrome = navigator.userAgent.match( /Chrome\/(\d+)/ );
var matchedEdge = navigator.userAgent.match( /Edge\// );
var matchedChrome = /chrome|crios\/(\d+)/i.test( ua );
var matchedEdge = /edge\//i.test( ua );
// MS Edge pretends to be Chrome 42:
// https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx
return !matchedEdge && matchedChrome;
},
isOnIos: function() {
return /iPad|iPhone|iPod/i.test( navigator.platform );
isSafari: function() {
return /^((?!chrome|android|fxios|crios|ucbrowser).)*safari/i.test( ua );
},
isFirefox: function() {
return /firefox|fxios/i.test( ua );
}
};

os = {
isIos: function() {
return /iPad|iPhone|iPod/i.test( ua );
},
isAndroid: function() {
return /android/i.test( ua );
}
};

module.exports = {
browser: browser
browser: browser,
os: os
};
2 changes: 1 addition & 1 deletion public/js/src/module/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ function _checkSupport() {
if ( typeof indexedDB === "object" ) {
resolve();
} else {
if ( sniffer.browser.isOnIos() ) {
if ( sniffer.os.isIos() ) {
error = new Error( t( 'store.error.iosusesafari' ) );
} else {
error = new Error( t( 'store.error.notsupported' ) );
Expand Down

0 comments on commit c7ed92a

Please sign in to comment.