diff --git a/.editconfig b/.editconfig
new file mode 100644
index 000000000..8f9bbe26e
--- /dev/null
+++ b/.editconfig
@@ -0,0 +1,20 @@
+# EditorConfig helps developers define and maintain consistent
+# coding styles between different editors and IDEs
+# editorconfig.org
+
+root = true
+
+[*]
+
+# Change these settings to your own preference
+indent_style = space
+indent_size = 2
+
+# We recommend you to keep these unchanged
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 823351c24..ec8506984 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,16 @@
* [CONFIG] There is no more dev/prod distinction, WPHC turn debug OFF when building the prod app automatically.
* [ABOUT] The About feature has been removed. You can use Pages to achieve the same purpose.
+
+### 2.0.0-beta13 (2016-10-22)
+
+To upgrade checkout `git checkout v2.0.0-beta13` and run `npm i`
+
+* [FEATURE] Display app icon in the menu header
+* [FEATURE] Progressive Web App support (Manifest & service workers)
+* Remove share button on browser
+
+
### 2.0.0-beta12 (2016-09-18)
diff --git a/CONFIGURATION.md b/CONFIGURATION.md
index 1be0e319b..914e1b236 100644
--- a/CONFIGURATION.md
+++ b/CONFIGURATION.md
@@ -81,6 +81,16 @@ For instance if you want to modify the way the menu is displayed, you will need
After that you will need to register your new template in `lib/templates/index.js` (read the comments for help)
+## Service Workers (Experimental)
+
+WPHC supports progressive web apps. When [enabled](#serviceWorker) make sure you modify `config/manifest.json` with your own app informations (title, description etc.) and overwrite all the icons in `config/icons`.
+
+PWA requires a HTTPS connection, make sure to have an SSL certificate.
+
+Chrome dev tools allow you to test the "add to homescreen" feature on the browser.
+
+![image](https://cloud.githubusercontent.com/assets/1388706/19619167/740031b0-9860-11e6-9ca0-ebb5bb9bb152.png)
+
## Frequently asked questions
### How to change the font
@@ -151,6 +161,7 @@ Here is a simple view of what you can configure:
* title
* ionicConfig
+* serviceWorker
* api
* baseUrl
* timeout
@@ -158,6 +169,7 @@ Here is a simple view of what you can configure:
* menu
* exposeAsideWhen
* list
+ * logo
* settings
* cache
* views
@@ -204,13 +216,15 @@ allow overwriting ionic configuration
+### serviceWorker [Object]
-The media query used to determine when to always display the left menu.
+* ***enabled*** ```Boolean``` Experiemental. default `false`
-```
-"exposeAsideWhen": "(min-width:900px)"
-```
+### menu [Object]
+
+* ***exposeAsideWhen*** ```String``` The media query used to determine when to always display the left menu, default `(min-width:900px)`
+* ***displayIcon*** ```Boolean``` whether or not to display the icon on the menu header. default `true`, to modify the icon overwrite `config/icons/icon_48.png`
### Settings configuration.
diff --git a/INSTALLATION.md b/INSTALLATION.md
index fbbb5033d..251f525fa 100644
--- a/INSTALLATION.md
+++ b/INSTALLATION.md
@@ -42,11 +42,6 @@ During the installation you might have the following error on OSX:
## Config files
-```
-# Copy local config
-npm run installWPHC
-```
-
Your personal config files live now in the `config` folder. You can modify all of them except `config.default.cson` which contains the default config that can be overwritten using `config/config.cson`
## Installing the Web service
diff --git a/PUSHNOTIFICATIONS.md b/PUSHNOTIFICATIONS.md
index 27845c651..ec34182e9 100644
--- a/PUSHNOTIFICATIONS.md
+++ b/PUSHNOTIFICATIONS.md
@@ -105,3 +105,9 @@ The register http request fails with this message: `{error: "401", reason: "Unau
Why am I getting the errors `{Unable to connect to tls://gateway.sandbox.push.apple.com:2195}` or `{Unable to connect to tsl://gateway.push.apple.com:2195}`?
[Solution](http://stackoverflow.com/questions/1444355/iphone-push-notification-unable-to-connect-to-the-ssl-server)
+
+### Param tells me that I am not registered
+
+If the "enabled" checkbox on the push notif parameters (in app) is never on. It could mean that the following checkboxes are not checked. Please check at least `category` to resolve the problem.
+
+![image](https://cloud.githubusercontent.com/assets/1388706/19411490/f5f52170-9302-11e6-9f31-28f9a97da691.png)
diff --git a/README.md b/README.md
index 54a599688..6052fff16 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,7 @@
- [X] Syntax highlighter
- [X] Offline (Bookmarks)
- [X] Comments (Submitting is not supported yet)
+- [X] Progressive Web App (manifest & Service Workers)
## Built with WPHC
@@ -78,7 +79,7 @@ $ git tag
$ git checkout
# Install
-$ npm install && npm run installWPHC
+$ npm install
# Run on the browser
$ npm start
@@ -123,6 +124,9 @@ Read the manual: [SPLASHICONS.md](SPLASHICONS.md)
## Project public API
```
+# Installation
+npm run installWPHC (auto ran post npm install)
+
# Dev server
npm start
diff --git a/config/config.default.cson b/config/config.default.cson
index c7b0d2a8f..fd23c756e 100755
--- a/config/config.default.cson
+++ b/config/config.default.cson
@@ -15,6 +15,9 @@
"timeout": 30000
"maxAttempt": 3
+"serviceWorker":
+ "enabled" : false
+
# IONIC
"ionicConfig":
"views":
@@ -49,6 +52,7 @@
"state": "public.posts"
"params": {}
"exposeAsideWhen": "(min-width:900px)"
+ "displayIcon": true # uses config/icons/icon_48.png
# SETTINGS PAGE
"settings":
diff --git a/dist/icons/icon_128.png b/dist/icons/icon_128.png
new file mode 100644
index 000000000..adfffcbb6
Binary files /dev/null and b/dist/icons/icon_128.png differ
diff --git a/dist/icons/icon_144.png b/dist/icons/icon_144.png
new file mode 100644
index 000000000..e35db6a7d
Binary files /dev/null and b/dist/icons/icon_144.png differ
diff --git a/dist/icons/icon_168.png b/dist/icons/icon_168.png
new file mode 100644
index 000000000..f9159a0c6
Binary files /dev/null and b/dist/icons/icon_168.png differ
diff --git a/dist/icons/icon_192.png b/dist/icons/icon_192.png
new file mode 100644
index 000000000..651730049
Binary files /dev/null and b/dist/icons/icon_192.png differ
diff --git a/dist/icons/icon_48.png b/dist/icons/icon_48.png
new file mode 100644
index 000000000..376d2a81f
Binary files /dev/null and b/dist/icons/icon_48.png differ
diff --git a/dist/icons/icon_72.png b/dist/icons/icon_72.png
new file mode 100644
index 000000000..5a11cc48a
Binary files /dev/null and b/dist/icons/icon_72.png differ
diff --git a/dist/icons/icon_96.png b/dist/icons/icon_96.png
new file mode 100644
index 000000000..b561e9502
Binary files /dev/null and b/dist/icons/icon_96.png differ
diff --git a/dist/index.js b/dist/index.js
index 1d5d3ccc7..a52c09872 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -1,4 +1,11 @@
import templates from './templates/index.js';
+import './icons/icon_48.png';
+import './icons/icon_72.png';
+import './icons/icon_96.png';
+import './icons/icon_144.png';
+import './icons/icon_168.png';
+import './icons/icon_192.png';
+import '!file?name=[name].[ext]!./manifest.json';
let mod = angular.module('wordpress-hybrid-client.overwriteModule', [
templates
diff --git a/dist/manifest.json b/dist/manifest.json
new file mode 100644
index 000000000..2a1f4099f
--- /dev/null
+++ b/dist/manifest.json
@@ -0,0 +1,43 @@
+{
+ "name": "Your App Name (45 characters max)",
+ "short_name": "Your App",
+ "description": "Your App description",
+ "default_locale": "en",
+ "start_url": "index.html",
+ "display": "standalone",
+ "lang": "en-US",
+ "icons": [
+ {
+ "src": "img/icon_48.png",
+ "sizes": "48x48",
+ "type": "image/png"
+ },
+ {
+ "src": "img/icon_72.png",
+ "sizes": "72x72",
+ "type": "image/png"
+ },
+ {
+ "src": "img/icon_96.png",
+ "sizes": "96x96",
+ "type": "image/png"
+ },
+ {
+ "src": "img/icon_144.png",
+ "sizes": "144x144",
+ "type": "image/png"
+ },
+ {
+ "src": "img/icon_168.png",
+ "sizes": "168x168",
+ "type": "image/png"
+ },
+ {
+ "src": "img/icon_192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ }
+ ],
+ "background_color": "#4e8ef7",
+ "theme_color": "#4e8ef7"
+}
\ No newline at end of file
diff --git a/lib/directives/postToolbar/index.js b/lib/directives/postToolbar/index.js
index dc1f35b7f..5a29ff239 100644
--- a/lib/directives/postToolbar/index.js
+++ b/lib/directives/postToolbar/index.js
@@ -19,8 +19,9 @@ export default function() {
var vm = this;
vm.isBookmarked = $WPHCBookmark.isBookmarked(vm.post);
vm.hasBookmark = angular.isDefined($attrs.showBookmark);
- vm.hasShare = angular.isDefined($attrs.showShare);
- vm.terms = vm.post._embedded['https://api.w.org/term'];
+ vm.hasShare = angular.isDefined($attrs.showShare) && ionic.Platform.isWebView();
+ vm.terms = vm.post._embedded['https://api.w.org/term']
+ || vm.post._embedded['wp:term'];
vm.showTaxonomies = showTaxonomies;
vm.share = share;
vm.bookmark = bookmark;
diff --git a/lib/index.coffee b/lib/index.coffee
index d2c34e4a7..c88493676 100644
--- a/lib/index.coffee
+++ b/lib/index.coffee
@@ -10,6 +10,7 @@ require './font/font.coffee'
require 'expose?_!lodash'
require 'wp-api-angularjs'
require './config.js'
+require '!file?name=[name].[ext]!./service-worker.js';
overwriteModule = require '../config/index.js'
customPostsModule = require './customPosts/index.js'
pagesModule = require './pages/index.js'
@@ -126,6 +127,7 @@ app.controller 'WPHCMainController' , ($log, $WPHCConfig) ->
vm.appVersion = wordpressHybridClient.version || null
vm.appConfig = $WPHCConfig
vm.appTitle = vm.appConfig.title || null
+ vm.displayIcon = vm.appConfig.menu.displayIcon
vm
###
diff --git a/lib/index.html b/lib/index.html
index a78aa930b..2468d66c6 100644
--- a/lib/index.html
+++ b/lib/index.html
@@ -7,10 +7,20 @@
{%=o.htmlWebpackPlugin.options.pkg.title %}
+
+ {% if (o.htmlWebpackPlugin.options.serviceWorkerEnabled) { %}
+
+ {% } %}
diff --git a/lib/scss/_bar.scss b/lib/scss/_bar.scss
old mode 100644
new mode 100755
index 399519128..957065c44
--- a/lib/scss/_bar.scss
+++ b/lib/scss/_bar.scss
@@ -1,3 +1,13 @@
+$logoSize : $bar-height - (2 * $bar-padding-portrait);
.bar {
+}
+.menu-bar.has-icon{
+ .icon{
+ width: $logoSize;
+ height: $logoSize;
+ }
+ .title{
+ margin-left: $logoSize + 10;
+ }
}
\ No newline at end of file
diff --git a/lib/scss/_post.scss b/lib/scss/_post.scss
old mode 100644
new mode 100755
index b06d23ec4..50aa00ef5
--- a/lib/scss/_post.scss
+++ b/lib/scss/_post.scss
@@ -162,4 +162,5 @@ wphc-post {
}
}
@include post-item("../img/post-img-border.png");
+
}
diff --git a/lib/service-worker.js b/lib/service-worker.js
new file mode 100644
index 000000000..0928a8fa5
--- /dev/null
+++ b/lib/service-worker.js
@@ -0,0 +1,80 @@
+// tick this to make the cache invalidate and update
+const CACHE_VERSION = 1;
+const CURRENT_CACHES = {
+ 'read-through': 'read-through-cache-v' + CACHE_VERSION
+};
+
+self.addEventListener('activate', (event) => {
+ // Delete all caches that aren't named in CURRENT_CACHES.
+ // While there is only one cache in this example, the same logic will handle the case where
+ // there are multiple versioned caches.
+ const expectedCacheNames = Object.keys(CURRENT_CACHES).map((key) => {
+ return CURRENT_CACHES[key];
+ });
+
+ event.waitUntil(
+ caches.keys().then((cacheNames) => {
+ return Promise.all(
+ cacheNames.map((cacheName) => {
+ if (expectedCacheNames.indexOf(cacheName) === -1) {
+ // If this cache name isn't present in the array of "expected" cache names, then delete it.
+ console.log('Deleting out of date cache:', cacheName);
+ return caches.delete(cacheName);
+ }
+ })
+ );
+ })
+ );
+});
+
+// This sample illustrates an aggressive approach to caching, in which every valid response is
+// cached and every request is first checked against the cache.
+// This may not be an appropriate approach if your web application makes requests for
+// arbitrary URLs as part of its normal operation (e.g. a RSS client or a news aggregator),
+// as the cache could end up containing large responses that might not end up ever being accessed.
+// Other approaches, like selectively caching based on response headers or only caching
+// responses served from a specific domain, might be more appropriate for those use cases.
+self.addEventListener('fetch', (event) => {
+
+ event.respondWith(
+ caches.open(CURRENT_CACHES['read-through']).then((cache) => {
+ return cache.match(event.request).then((response) => {
+ if (response) {
+ // If there is an entry in the cache for event.request, then response will be defined
+ // and we can just return it.
+
+ return response;
+ }
+
+ // Otherwise, if there is no entry in the cache for event.request, response will be
+ // undefined, and we need to fetch() the resource.
+ console.log(' No response for %s found in cache. ' +
+ 'About to fetch from network...', event.request.url);
+
+ // We call .clone() on the request since we might use it in the call to cache.put() later on.
+ // Both fetch() and cache.put() "consume" the request, so we need to make a copy.
+ // (see https://fetch.spec.whatwg.org/#dom-request-clone)
+ return fetch(event.request.clone()).then((response) => {
+
+ // Optional: add in extra conditions here, e.g. response.type == 'basic' to only cache
+ // responses from the same domain. See https://fetch.spec.whatwg.org/#concept-response-type
+ if (response.status < 400 && response.type === 'basic') {
+ // We need to call .clone() on the response object to save a copy of it to the cache.
+ // (https://fetch.spec.whatwg.org/#dom-request-clone)
+ cache.put(event.request, response.clone());
+ }
+
+ // Return the original response object, which will be used to fulfill the resource request.
+ return response;
+ });
+ }).catch((error) => {
+ // This catch() will handle exceptions that arise from the match() or fetch() operations.
+ // Note that a HTTP error response (e.g. 404) will NOT trigger an exception.
+ // It will return a normal response object that has the appropriate error code set.
+ console.error(' Read-through caching failed:', error);
+
+ throw error;
+ });
+ })
+ );
+});
\ No newline at end of file
diff --git a/lib/templates/module/menu.html b/lib/templates/module/menu.html
index b6a7802dd..23520a3ed 100644
--- a/lib/templates/module/menu.html
+++ b/lib/templates/module/menu.html
@@ -1,6 +1,7 @@
-
-