Add appcache support for offline standalone app

This commit is contained in:
Colin McLeod
2015-05-27 23:59:54 -07:00
parent 1796b0fb46
commit 280411f35c
27 changed files with 98 additions and 20 deletions

View File

@@ -1,5 +1,6 @@
{ {
"name": "Shipyard", "name": "Coriolis.io",
"short_name": "Coriolis",
"icons": [ "icons": [
{ {
"src": "images\/logo\/android-chrome-36x36.png", "src": "images\/logo\/android-chrome-36x36.png",

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
app/images/splash/1280x720.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
app/images/splash/200x320.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
app/images/splash/320x200.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
app/images/splash/320x480.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
app/images/splash/480x320.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
app/images/splash/480x800.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
app/images/splash/720x1280.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
app/images/splash/800x480.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -1,30 +1,69 @@
<!DOCTYPE html> <!DOCTYPE html>
<html ng-app="app" ng-strict-di="true"> <html ng-app="app" ng-strict-di="true" manifest="coriolis.appcache">
<head> <head>
<title ng-bind="title">Coriolis</title> <title ng-bind="title">Coriolis</title>
<link rel="stylesheet" href="/app.css"> <link rel="stylesheet" href="/app.css">
<!-- Standard headers -->
<meta name="mobile-web-app-capable" content="yes">
<meta name="viewport" content="width = device-width, initial-scale = 1.0">
<link rel="manifest" href="/images/logo/manifest.json">
<link rel="icon" sizes="96x96" type="image/png" href="/images/logo/favicon-96x96.png">
<link rel="icon" sizes="194x194" type="image/png" href="/images/logo/favicon-194x194.png">
<link rel="icon" sizes="192x192" type="image/png" href="/images/logo/android-chrome-192x192.png">
<link rel="shortcut icon" href="/images/logo/favicon.ico">
<!-- Apple/iOS headers -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-title" content="Coriolis">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="apple-touch-icon" sizes="76x76" href="/images/logo/apple-touch-icon-76x76.png"> <link rel="apple-touch-icon" sizes="76x76" href="/images/logo/apple-touch-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/images/logo/apple-touch-icon-114x114.png"> <link rel="apple-touch-icon" sizes="114x114" href="/images/logo/apple-touch-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/images/logo/apple-touch-icon-120x120.png"> <link rel="apple-touch-icon" sizes="120x120" href="/images/logo/apple-touch-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/images/logo/apple-touch-icon-144x144.png"> <link rel="apple-touch-icon" sizes="144x144" href="/images/logo/apple-touch-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/images/logo/apple-touch-icon-152x152.png"> <link rel="apple-touch-icon" sizes="152x152" href="/images/logo/apple-touch-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/images/logo/apple-touch-icon-180x180.png"> <link rel="apple-touch-icon" sizes="180x180" href="/images/logo/apple-touch-icon-180x180.png">
<link rel="icon" sizes="96x96" type="image/png" href="/images/logo/favicon-96x96.png"> <!-- iPhone, iPod Touch, portrait -->
<link rel="icon" sizes="194x194" type="image/png" href="/images/logo/favicon-194x194.png"> <link href="/images/splash/320x460.png" media="(device-width: 320px) and (device-height: 480px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 1)" rel="apple-touch-startup-image">
<link rel="icon" sizes="192x192" type="image/png" href="/images/logo/android-chrome-192x192.png"> <!-- iPhone, iPod Touch, landscape -->
<link rel="manifest" href="/images/logo/manifest.json"> <link href="/images/splash/480x320.png" media="(device-width: 320px) and (device-height: 480px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 1)" rel="apple-touch-startup-image">
<link rel="shortcut icon" href="/images/logo/favicon.ico"> <!-- iPhone 4, 4S, portrait -->
<link href="/images/splash/640x920.png" media="(device-width: 320px) and (device-height: 480px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image">
<!-- iPhone 4, 4S, landscape -->
<link href="/images/splash/960x640.png" media="(device-width: 320px) and (device-height: 480px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image">
<!-- iPhone 5, 5S, 5C, portrait -->
<link href="/images/splash/640x1096.png" media="(device-width: 320px) and (device-height: 568px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image">
<!-- iPhone 5, 5S, 5C, landscape -->
<link href="/images/splash/1136x640.png" media="(device-width: 320px) and (device-height: 568px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image">
<!-- iPhone 6, portrait -->
<link href="/images/splash/750x1294.png" media="(device-width: 375px) and (device-height: 667px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image">
<!-- iPhone 6, landscape -->
<link href="/images/splash/1334x750.png" media="(device-width: 375px) and (device-height: 667px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image">
<!-- iPhone 6+, portrait -->
<link href="/images/splash/1242x2148.png" media="(device-width: 414px) and (device-height: 736px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image">
<!-- iPhone 6+, landscape -->
<link href="/images/splash/2208x1242.png" media="(device-width: 414px) and (device-height: 736px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image">
<!-- iPad 1, 2, Mini, portrait -->
<link href="/images/splash/768x1004.png" media="(device-width: 768px) and (device-height: 1024px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 1)" rel="apple-touch-startup-image">
<!-- iPad 1, 2, Mini, landscape -->
<link href="/images/splash/1024x748.png" media="(device-width: 768px) and (device-height: 1024px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 1)" rel="apple-touch-startup-image">
<!-- iPad 3, 4, Air, Air 2, Mini 2, Mini 3, portrait -->
<link href="/images/splash/1536x2008.png" media="(device-width: 768px) and (device-height: 1024px) and (orientation: portrait) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image">
<!-- iPad 3, 4, Air, Air 2, Mini 2, Mini 3, landscape -->
<link href="/images/splash/2048x1496.png" media="(device-width: 768px) and (device-height: 1024px) and (orientation: landscape) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image">
<!-- Microsoft Windows Phone/Tablet headers -->
<meta name="msapplication-TileColor" content="#da532c"> <meta name="msapplication-TileColor" content="#da532c">
<meta name="msapplication-TileImage" content="/images/logo/mstile-144x144.png"> <meta name="msapplication-TileImage" content="/images/logo/mstile-144x144.png">
<meta name="msapplication-config" content="/images/logo/browserconfig.xml"> <meta name="msapplication-config" content="/images/logo/browserconfig.xml">
<meta name="theme-color" content="#000000"> <meta name="theme-color" content="#000000">
</head> </head>
<body> <body style="background-color:#000;">
<div style="height: 0; width: 0; overflow:hidden"><%= svgContent %></div> <div style="height: 0; width: 0; overflow:hidden"><%= svgContent %></div>
<shipyard-header></shipyard-header> <shipyard-header></shipyard-header>
<div id="main" ui-view ng-click="bgClicked($event)"></div> <div id="main" ui-view ng-click="bgClicked($event)"></div>
<div ui-view="modal"></div> <div ui-view="modal" ng-click="bgClicked($event)"></div>
<footer> <footer>
<div class="right"> <div class="right">

View File

@@ -1,14 +1,18 @@
/** /**
* BBCode Generator functions for embedding in the Elite Dangerous Forums * BBCode Generator functions for embedding in the Elite Dangerous Forums
*/ */
angular.module('app').factory('Utils', ['$state','$http', function ($state, $http) { angular.module('app').factory('Utils', ['$window','$state','$http', '$q', function ($window, $state, $http, $q) {
var shortenAPI = 'https://www.googleapis.com/urlshortener/v1/url?key='; var shortenAPI = 'https://www.googleapis.com/urlshortener/v1/url?key=';
function shortenUrl(url) { function shortenUrl(url) {
return $http.post(shortenAPI + GAPI_KEY, {longUrl:url}).then(function(response) { if ($window.navigator.onLine) {
return response.data.id; return $http.post(shortenAPI + GAPI_KEY, {longUrl:url}).then(function(response) {
}); return response.data.id;
});
} else {
return $q.reject({statusText: 'Not Online'});
}
} }
function comparisonBBCode(facets, builds, link) { function comparisonBBCode(facets, builds, link) {

View File

@@ -1,5 +1,4 @@
var gulp = require('gulp'), var gulp = require('gulp'),
exec = require('gulp-exec'),
less = require('gulp-less'), less = require('gulp-less'),
jshint = require('gulp-jshint'), jshint = require('gulp-jshint'),
minifyCSS = require('gulp-minify-css'), minifyCSS = require('gulp-minify-css'),
@@ -19,6 +18,7 @@ var gulp = require('gulp'),
svgstore = require( 'gulp-svgstore' ), svgstore = require( 'gulp-svgstore' ),
svgmin = require( 'gulp-svgmin' ), svgmin = require( 'gulp-svgmin' ),
jsonlint = require("gulp-jsonlint"), jsonlint = require("gulp-jsonlint"),
appCache = require("gulp-manifest"),
pkg = require('./package.json'); pkg = require('./package.json');
var cdnHostStr = ''; var cdnHostStr = '';
@@ -167,11 +167,12 @@ gulp.task('serve-stop', function(cb) {
gulp.task('watch', function() { gulp.task('watch', function() {
gulp.watch(['app/index.html','app/icons/*.svg'], ['generateIndexHTML']); gulp.watch(['app/index.html','app/icons/*.svg'], ['generateIndexHTML']);
gulp.watch(['app/images/**','app/fonts/**', 'app/.htaccess'], ['copy']); gulp.watch(['app/images/**','app/fonts/**'], ['copy']);
gulp.watch('app/less/*.less', ['less']); gulp.watch('app/less/*.less', ['less']);
gulp.watch('app/views/**/*', ['html2js']); gulp.watch('app/views/**/*', ['html2js']);
gulp.watch('app/js/**/*.js', ['js']); gulp.watch('app/js/**/*.js', ['js']);
gulp.watch('data/**/*.json', ['jsonToDB']); gulp.watch('data/**/*.json', ['jsonToDB']);
gulp.watch(['build/**', '!**/*.appcache'], ['appcache']);
}); });
gulp.task('cache-bust', function(done) { gulp.task('cache-bust', function(done) {
@@ -195,6 +196,29 @@ gulp.task('cache-bust', function(done) {
stream.on('error', done); stream.on('error', done);
}); });
gulp.task('appcache', function(done) {
// Since using a CDN manually build file list rather than using appCache mechanisms
gulp.src(['build/**', '!build/index.html', '!**/*.json', '!**/logo/*', '!**/*.map','!**/*.appcache'])
.pipe(gutil.buffer(function(err, stream) {
var files = [];
for (var i = 0; i < stream.length; i++) {
if (!stream[i].isNull()) {
files.push(cdnHostStr + '/' + stream[i].relative);
}
}
gulp.src([])
.pipe(appCache({
preferOnline: true,
cache: files,
filename: 'coriolis.appcache',
timestamp: true
}))
.pipe(gulp.dest('build'))
.on('end', done);
}));
});
gulp.task('upload', function(done) { gulp.task('upload', function(done) {
exec([ exec([
"rsync -e 'ssh -i ", process.env.CORIOLIS_PEM, "' -a --delete build/ ", process.env.CORIOLIS_USER, "@", process.env.CORIOLIS_HOST, ":~/www" "rsync -e 'ssh -i ", process.env.CORIOLIS_PEM, "' -a --delete build/ ", process.env.CORIOLIS_USER, "@", process.env.CORIOLIS_HOST, ":~/www"
@@ -206,11 +230,11 @@ gulp.task('upload', function(done) {
gulp.task('lint', ['js-lint', 'json-lint']); gulp.task('lint', ['js-lint', 'json-lint']);
gulp.task('clean', function (done) { del(['build'], done); }); gulp.task('clean', function (done) { del(['build'], done); });
gulp.task('build', function (done) { runSequence('clean', ['html2js','jsonToDB'], ['generateIndexHTML','bower','js','less','copy'], done); }); gulp.task('build', function (done) { runSequence('clean', ['html2js','jsonToDB'], ['generateIndexHTML','bower','js','less','copy'], done); });
gulp.task('build-cache', function (done) { runSequence('build', 'appcache', done); });
gulp.task('dev', function (done) { runSequence('build-cache', 'serve','watch', done); });
gulp.task('deploy', function (done) { gulp.task('deploy', function (done) {
cdnHostStr = '//cdn.' + process.env.CORIOLIS_HOST; cdnHostStr = '//cdn.' + process.env.CORIOLIS_HOST;
runSequence('lint', 'build','cache-bust', 'upload', done); runSequence('lint', 'build','cache-bust', 'appcache', 'upload', done);
}); });
gulp.task('dev', function (done) { runSequence('build', 'serve','watch', done); });
gulp.task('default', ['dev']); gulp.task('default', ['dev']);

View File

@@ -25,6 +25,7 @@ http {
image/svg+xml svg; image/svg+xml svg;
image/x-icon ico; image/x-icon ico;
application/pdf pdf; application/pdf pdf;
text/cache-manifest appcache;
} }
gzip on; gzip on;
@@ -41,6 +42,15 @@ http {
root ./build/; root ./build/;
index index.html; index index.html;
location ~* \.(?:manifest|appcache|html?|xml|json|css|js|map|jpg|jpeg|gif|png|ico|svg|eot|ttf|woff|woff2)$ {
expires -1;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
access_log off;
}
location / { location / {
try_files $uri $uri/ /index.html =404; try_files $uri $uri/ /index.html =404;
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "coriolis_shipyard", "name": "coriolis_shipyard",
"version": "0.8.0", "version": "0.8.1",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/cmmcleod/coriolis" "url": "https://github.com/cmmcleod/coriolis"
@@ -13,11 +13,11 @@
"gulp": "^3.8.11", "gulp": "^3.8.11",
"gulp-angular-templatecache": "^1.6.0", "gulp-angular-templatecache": "^1.6.0",
"gulp-concat": "^2.5.2", "gulp-concat": "^2.5.2",
"gulp-exec": "^2.1.1",
"gulp-htmlmin": "^1.1.1", "gulp-htmlmin": "^1.1.1",
"gulp-jshint": "^1.10.0", "gulp-jshint": "^1.10.0",
"gulp-jsonlint": "^1.0.2", "gulp-jsonlint": "^1.0.2",
"gulp-less": "^3.0.2", "gulp-less": "^3.0.2",
"gulp-manifest": "0.0.6",
"gulp-minify-css": "^1.0.0", "gulp-minify-css": "^1.0.0",
"gulp-rev-all": "^0.8.18", "gulp-rev-all": "^0.8.18",
"gulp-sourcemaps": "^1.5.1", "gulp-sourcemaps": "^1.5.1",