Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
brucemcpherson committed May 24, 2017
0 parents commit ed52f6d
Show file tree
Hide file tree
Showing 8 changed files with 1,025 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
src/mapsApiKey.js
4 changes: 4 additions & 0 deletions README.md
@@ -0,0 +1,4 @@
# effex-demo-markers
A demo using the Ephemeral Exchange API to connect a Maps app to various back ends

Read more about this at http://ramblings.mcpher.com/Home/excelquirks/ephemeralexchange/sheetsmaps
Binary file added img/exn64.ico
Binary file not shown.
110 changes: 110 additions & 0 deletions index.html
@@ -0,0 +1,110 @@
<!DOCTYPE html>
<html>
<head>
<title>effex-demo-markers</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- load MUI -->
<link href="https://cdn.muicss.com/mui-0.9.9/css/mui.min.css" rel="stylesheet" type="text/css" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="shortcut icon" href="img/exn64.ico" type="image/x-icon">
<script src="https://cdn.muicss.com/mui-0.9.9/js/mui.min.js"></script>

<style>

#map {
height: 100%;
margin-left: 210px;

}

#panel {
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 5;
background-color: #fff;
width:180px;

}

#errify {
height:110px;
position: absolute;
bottom: 0;
left: 0;
width:180px;
padding:15px;
}

html, body {
height: 100%;
margin: 0;
padding: 0;
}

.iconlink {
cursor:pointer;
}

#camera {
position:absolute;
display:block;
background-color:white;
width:24px;
height:56px;
top:40px;
right:20px;
z-index:6;
}

</style>
</head>


<div id="map"></div>
<div id="camera" class="mui--hide">
<div class="inconlink">
<i id="snap" class="material-icons">photo_camera</i>
<i id="reset" class="material-icons">restore_page</i>
</div>
</div>
<div id="panel" class="mui-panel" style="padding-top:0;padding-bottom:0;margin:0;">
<h4>Effex store data</h4>
<div class="mui-divider"></div>
<div>Updater key</div>
<div id="efx-key" style="font-size:.7em;"></div>
<div>Item key</div>
<div id="efx-id" style="font-size:.7em;"></div>
<div class="mui-divider"></div>
<br>
<div class="mui--text-dark-secondary">
<div>Collecting data using maps</div>
<ul><br>
<li>Clicking on a marker allows you to modify its contents, or to delete it</li>.
<li>Right click somewhere on the map to drop in a new marker"</li>
</ul>
</div>
<div style="padding-top:40px;">
<div>When finished, update the store to send back changes</div>
<div><br></div>
<button id="update" class="mui-btn mui-btn--primary">Update store</button>
</div>

<div id="errify" class="mui--bg-danger mui--hide mui--text-white mui--text-caption"></div>
</div>
<script src="https://www.google.com/jsapi"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.1.20150312/classList.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.0.5/es6-promise.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.15.3/axios.min.js"></script>

<script src="lib/effexapiclient.js"></script>
<script src="src/mapsApiKey.js"></script>
<script src="src/maps.js"></script>
<script src="src/main.js"></script>

</body>

</html>
201 changes: 201 additions & 0 deletions lib/effexapiclient.js
@@ -0,0 +1,201 @@
/**
* @namespace EffexApiClient
* lite effex API client, with no admin capabilities
*/
/* global axios */
var EffexApiClient = (function(ns) {

// the api base url
var ax,keys;

ns.setKeys = function (optionalKeys){
keys = optionalKeys || ns.getUriKeys();
};

ns.getKeys = function () {
return keys;
};

ns.setBase = function(base) {
ax = axios.create({
baseURL: base,
maxContentLength: 512000
});
};



function clone (ob) {
return JSON.parse(JSON.stringify(ob || {}));
}

/**
* turns a params object into a url
* @param {object} params the params
* @return {string} the uri
*/
function makeParams(params) {
params = params || {};
var pa = Object.keys(params).reduce(function(p, c) {
p.push(c + "=" + encodeURIComponent(params[c]));
return p;
}, []);

return pa.length ? ("?" + pa.join("&")) : "";
}

ns.checkKeys = function (preview) {
if (!Array.isArray(preview)) preview = [preview];
return preview.every(function(d){ return keys[d]});
};

/**
* @param {string} boss the boss key
* @param {string} mode the type like writer/reader/updater
* @param {object} params the params
* @return {Promise} to the result
*/
ns.generateKey = function (boss, mode,params) {
return ax.get ('/' + boss + '/' + mode + makeParams(params));
};

/**
* ping the service
* @return {object} "PONG"
*/
ns.ping = function() {
return ax.get('/ping');
};

/**
* info the service
* @return {object} result
*/
ns.info = function() {
return ax.get('/info');
};

/**
* get quotas
* @return {object} the quotas
*/
ns.getQuotas = function() {
return ax.get('/quotas');
};

/**
* update an item
* @param {string} id the item id
* @param {string} updater the updater key
* @param {object} data what to write
* @param {string} method the to use (post,get)
* @param {object} params the params
* @return {Promise} to the result
*/
ns.update = function (data, id, updater, method , params) {
method = (method || "post").toLowerCase();
params = params || {};

if (method === "get") {
params = clone(params);
params.data = JSON.stringify(data);
}
var url = "/updater/" + ns.checkKey("updater",updater) + "/" + ns.checkKey("item",id) + makeParams(params);
return ax[method] (url, {data:data});
};

/**
* @param {string} writer the writer key
* @param {object} data what to write
* @param {string} method the to use (post,get)
* @param {object} params the params
* @return {Promise} to the result
*/
ns.write = function (data, writer, method , params) {
method = (method || "post").toLowerCase();
params = params || {};

if (method === "get") {
params = clone(params);
params.data = JSON.stringify(data);
}
var url = "/writer/" + ns.checkKey("writer",writer) + makeParams(params);
return ax[method] (url, {data:data});
};


ns.checkKey = function (type, value) {
var k= value || keys[type];
if (!k) console.log ("failed key check", type, value);
return k;
};


/**
* @param {string} id the item id
* @param {string} writer the writer key
* @param {object} params the params
* @return {Promise} to the result
*/
ns.remove = function (id, writer , params) {
return ax.remove ('/writer/' + ns.checkKey("writer",writer) + '/' + ns.checkKey("item",id) + makeParams(params || []));
};

ns.read = function (id, reader , params) {
params = params || {};
id = id || keys.item;
reader = reader || keys.reader;
return ax.get ('/reader/' + ns.checkKey("reader",reader) + '/' + ns.checkKey("item",id) + makeParams(params));
};

/**
* @param {string} coupon the coupon code
* @return {Promise} to the result
*/
ns.validateKey = function (coupon) {
return ax.get ('/validate/' + coupon);
};

/**
* @param {string} id the item id
* @param {string} writer the writer key
* @param {string} key the key to assign the alias for
* @param {string} alias the alias to assign
* @param {object} params the params
* @return {Promise} to the result
*/
ns.registerAlias = function (writer, key, id , alias, params) {
return ax.get('/'+ ns.checkKey("writer",writer) + '/' + key +
'/alias/' + encodeURIComponent(alias) + '/' + ns.checkKey("item",id) + makeParams(params));
};

ns.getUriParam = function (name, source) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(source || window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
};

/**
* standard parameters that might useful for an effex app
* @return {object} keys
*/
ns.getUriKeys = function() {
var ob = ["updater", "reader", "item","boss","writer"]
.reduce(function(p, c) {
p[c] = ns.getUriParam(c);
return p;
}, {});

// updaters/writers can standin for readers
ob.updater = ob.updater || ob.writer;
ob.reader = ob.reader || ob.updater || ob.writer;

return ob;
};

// default prod
ns.setBase("https://ephex-auth.appspot-preview.com");
ns.setKeys();
axios.defaults.headers.post['Content-Type'] = 'application/json';

return ns;
})({});
72 changes: 72 additions & 0 deletions src/main.js
@@ -0,0 +1,72 @@
/* global google */
/* global Maps */
/* global EffexApiClient */
/* global getMapsApiKey */

google.load('maps', '3', {
callback: function() {

// this particular app is expecting to read and update an item, so ensure we have keys for that
if (!EffexApiClient.checkKeys(["updater", "reader", "item"])) {
errify('missing uri parameters', 'both an updater key and an item key are required');
}

else {
// give some info
document.getElementById("efx-id").innerHTML = EffexApiClient.getKeys().item;
document.getElementById("efx-key").innerHTML = EffexApiClient.getKeys().updater;

var maps;
// and get the data
EffexApiClient.read()
.then(function(response) {
if (response.data && response.data.ok) {
// initialize the map and get going
maps = new Maps().init(response.data);
}
else {
errify("Failed to get effexdata", JSON.stringify(response));
}
})
.catch(function(err) {
errify("grevious error getting data", err);
});

// hook up the update button
document.getElementById("update")
.addEventListener("click", function() {
EffexApiClient.update(maps.spots.map(function(d) {
return d.place;
}))
.then(function(result) {
if (result.data && result.data.ok) {
errify("Effex updated", maps.spots.length + " spots sent");
}
else {
errify("Failed to update effexdata", JSON.stringify(result));
}
})
.catch(function(err) {
errify("grevious error updating data", err);
});
});
}


},


other_params: 'key=' + getMapsApiKey()

});

// error messages
function errify(message, error) {
var ef = document.getElementById("errify");
ef.classList.remove ("mui--hide");
ef.innerHTML = message + '<br>' + error;
console.log(message, error);
setTimeout(function () {
ef.classList.add ("mui--hide");
}, 5000);
}

0 comments on commit ed52f6d

Please sign in to comment.