Newer
Older
francois.grand
committed
<head>
<base href="">
<meta charset="utf-8">
<title>Cassiopée</title>
<link rel="apple-touch-icon" sizes="180x180" href="assets/icons/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="512x512" href="assets/icons/android-chrome-512x512.png">
<link rel="icon" type="image/png" sizes="192x192" href="assets/icons/android-chrome-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="assets/icons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="assets/icons/favicon-16x16.png">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#ffffff">
<meta name="viewport" content="width=device-width, initial-scale=1">
francois.grand
committed
</head>
<body>
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<nghyd-app>
<style type="text/css">
body,
html {
height: 100%;
}
.app-loading {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
border: solid red 100%;
font-family: Arial, Helvetica, sans-serif;
}
.app-loading>.logo {
margin-bottom: 10px;
}
</style>
<div class="app-loading">
<div class="logo">
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" id="svg3406" version="1.1"
inkscape:version="0.92.3 (2405546, 2018-03-11)" width="167.55714" height="167.55714"
viewBox="0 0 167.55714 167.55714" sodipodi:docname="cassiopee_logo.svg">
<metadata id="metadata3412">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" ></dc:type>
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs id="defs3410"></defs>
<g inkscape:groupmode="layer" id="layer1" inkscape:label="background">
<rect
style="fill:#003a80;stroke:none;stroke-width:8;stroke-miterlimit:4;stroke-dasharray:none;fill-opacity:1;stroke-opacity:1;stroke-linejoin:round"
id="fond" width="165.55714" height="165.55714" x="1" y="1"></rect>
</g>
<g inkscape:groupmode="layer" id="calque_traits" inkscape:label="traits">
<path
style="fill:#80b3ff;fill-rule:evenodd;stroke:#4dbbe9;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 16.234557,39.786389 36.297745,77.631687" id="trait_1" inkscape:connector-curvature="0"></path>
<path
style="fill:#80b3ff;fill-rule:evenodd;stroke:#4dbbe9;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 47.234816,83.975938 27.27422,0.39174" id="trait_2" inkscape:connector-curvature="0"></path>
<path
style="fill:#80b3ff;fill-rule:evenodd;stroke:#4dbbe9;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 85.615846,92.002058 101.01379,128.05358" id="trait_3" inkscape:connector-curvature="0"></path>
<path
style="fill:#80b3ff;fill-rule:evenodd;stroke:#4dbbe9;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 145.82968,107.86632 -35.62153,23.78874" id="trait_4" inkscape:connector-curvature="0"></path>
</g>
<g inkscape:groupmode="layer" id="calque_points" inkscape:label="points">
<circle
style="fill:#ffffff;stroke:#003a80;stroke-width:10;stroke-miterlimit:66;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="point_1" cx="12.879179" cy="34.64555" r="6"></circle>
<circle
style="fill:#ffffff;stroke:#003a80;stroke-width:10;stroke-miterlimit:66;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="point_2" cx="39.734871" cy="83.581924" r="10"></circle>
<circle
style="fill:#ffffff;stroke:#003a80;stroke-width:10;stroke-linejoin:round;stroke-miterlimit:66;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="point_3" cx="82.500542" cy="84.860001" r="10"></circle>
<circle
style="fill:#ffffff;stroke:#003a80;stroke-width:10;stroke-miterlimit:66;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="point_4" cx="104.12913" cy="135.35852" r="10"></circle>
<circle
style="fill:#ffffff;stroke:#003a80;stroke-width:10;stroke-miterlimit:66;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke markers fill"
id="point_5" cx="151.57199" cy="103.73587" r="10"></circle>
</g>
</svg>
</div>
Loading Cassiopée…
<script type="text/javascript">
// animation du logo
// CONFIG
var elements1 = [ "trait_1", "trait_2", "trait_3", "trait_4", "point_1", "point_2", "point_3", "point_4", "point_5" ];
var elements2 = [ "point_1", "point_2", "point_3", "point_4", "point_5", "trait_1", "trait_2", "trait_3", "trait_4" ];
var delayB = 100; // delay betweeen elements
var delayO = 40; // delay between opacity change
var stepO = 0.1; // opacity change step
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
var animationTime = (elements1.length * delayB + (1 / stepO) * delayO);
oneAnimation();
var animationLoop = setInterval(() => {
// do one animation
oneAnimation();
// if DOM elements are gone (Angular has loaded), stop animation loop
var testElt = document.getElementById(elements1[0]);
if (! testElt) {
clearInterval(animationLoop);
}
}, 2 * animationTime);
function oneAnimation() {
hideSequence(elements1, delayB, delayO, stepO);
setTimeout(() => {
showSequence(elements2, delayB, delayO, stepO);
}, animationTime);
}
function hideSequence(ids, delayBetween = 500, delay = 100, step = 0.1) {
callSequence(hideSmooth, ids, delayBetween, delay, step);
}
function showSequence(ids, delayBetween = 500, delay = 100, step = 0.1) {
callSequence(showSmooth, ids, delayBetween, delay, step);
}
function callSequence(func, ids, delayBetween = 500, delay = 100, step = 0.1) {
for (var i = 0; i < ids.length; i++) {
var id = ids[i];
var d;
if (i === 0) {
d = 0;
} else {
d += delayBetween;
}
((locId) => {
setTimeout(() => {
func(locId, delay, step);
}, d);
})(id);
}
}
function hideSmooth(id, delay = 100, step = 0.1) {
var element = document.getElementById(id);
if (element) {
element.style.opacity = 1;
var loopHandle = setInterval(() => {
if (element.style.opacity > minOpacity) {
element.style.opacity = String(Number(element.style.opacity) - Number(step));
} else {
clearInterval(loopHandle);
}
}, delay);
}
}
function showSmooth(id, delay = 100, step = 0.1) {
var element = document.getElementById(id);
if (element) {
element.style.opacity = minOpacity;
var loopHandle = setInterval(() => {
if (element.style.opacity < 1) {
element.style.opacity = String(Number(step) + Number(element.style.opacity));
} else {
clearInterval(loopHandle);
}
}, delay);
}
}
</script>
</nghyd-app>
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
<script type="text/javascript">
/**
* Compares semver strings
* @see https://github.com/substack/semver-compare
*/
function semverCompare(a, b) {
var pa = a.split('.');
var pb = b.split('.');
for (var i = 0; i < 3; i++) {
var na = Number(pa[i]);
var nb = Number(pb[i]);
if (na > nb) return 1;
if (nb > na) return -1;
if (!isNaN(na) && isNaN(nb)) return 1;
if (isNaN(na) && !isNaN(nb)) return -1;
}
return 0;
}
/**
* Calls the Cassiopee update server to check for available updates;
* if so, displays a desktop notification which, if clicked, will
* trigger the download of the latest version installer for the
* current platform
*
* Web updates system prerequisites
* --------------------------------
*
* ${URL} should point to an http-accessible directory containing:
*
* 1. a file named "releases.json" with a contents of the form
* {
* "latest": "4.5.0",
* "4.5.0": {
* "darwin": "cassiopee-setup-4.5.0.dmg",
* "linux": "fr.irstea.cassiopee_4.5.0_amd64.deb",
* "win32": "Cassiopée Setup 4.5.0.exe"
* },
* "4.4.2": {
* "darwin": "cassiopee-setup-4.4.2.dmg",
* "linux": "fr.irstea.cassiopee_4.4.2_amd64.deb",
* "win32": "Cassiopée Setup 4.4.2.exe"
* }
* }
*
* 2. all platform-dependent installer files specified in "releases.json",
* at the root of the directory (ex: "fr.irstea.cassiopee_4.5.0_amd64.deb")
*/
const lookForUpdates = function() {
console.log("looking for updates");
// Web update resources root directory
const URL = "https://cassiopee.g-eau.fr/cassiopee-releases/";
// detect current app version and platform
let version = "4.4.2"; // debug
cordova.getAppVersion.getVersionNumber((versionNumber) => {
version = versionNumber;
console.log("current version", version);
// fetch releases information
const options = {
method: 'get',
headers: { "Cache-Control": "no-cache" }
};
cordova.plugin.http.sendRequest(URL + "releases.json", options, (response) => {
var data = JSON.parse(response.data); // This is the resultant JSON in useful form
// alert(`Youpi ! ${response.status} version=${version}, latest=${data.latest}, comp=${semverCompare(data.latest, version)}`);
console.log("latest version", data !== undefined ? data.latest : "err");
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
// compare current version to latest version
if (data.latest && semverCompare(data.latest, version) == 1) {
// get download link for latest version, depending on platform
if (data[data.latest] && data[data.latest]["android"]) {
const latestVersionURL = URL + data[data.latest]["android"];
// show notification
cordova.plugins.notification.local.schedule({
title: `Cassiopee version ${data.latest} is available`,
text: "Download update installer",
foreground: true,
smallIcon: "res://ic_stat_notify",
icon: "res://icon"
});
cordova.plugins.notification.local.on("click", () => {
// ask system to open URL with default browser
// @TODO find a way to get rid of "are you sure you want to leave this page ?" prompt
window.open(latestVersionURL, "_system");
});
} // else could not find link, silent fail
} // else you already have the latest version
}, (response) => { /* silent fail */});
});
};
// execute on Cordova (mobile app) only
if (window.cordova && cordova.platformId !== "browser") {
document.addEventListener("deviceready", function () {
// check updates at app startup
lookForUpdates();
});
}
</script>
francois.grand
committed
</body>
</html>