Hello world

This commit is contained in:
2020-01-02 13:51:50 -05:00
commit 4b42391f4e
13 changed files with 539 additions and 0 deletions

28
modules/dom-helpers.mjs Normal file
View File

@@ -0,0 +1,28 @@
function hideElement (selector) {
document.querySelector(selector)
.classList.add('hidden');
}
function showElement (selector) {
document.querySelector(selector)
.classList.remove('hidden');
}
function updateHTML (selector, content) {
document.querySelector(selector).innerHTML = content;
}
function renderImage (parentSelector, imageUrl, size) {
const imageEl = document.createElement('img');
imageEl.setAttribute("src", imageUrl);
if (size) {
const [ width, height ] = size.split('x');
imageEl.setAttribute("width", width);
imageEl.setAttribute("height", height);
}
const parentEl = document.querySelector(parentSelector);
parentEl.innerHTML = '';
parentEl.appendChild(imageEl);
}
export { hideElement, showElement, updateHTML, renderImage };

20
modules/geocode.mjs Normal file
View File

@@ -0,0 +1,20 @@
export default class Geocoder {
constructor (remoteStorage) {
this.rs = remoteStorage;
}
async reverse (lat, lng) {
const q = `${lat}+${lng}&no_record=1&min_confidence=3`;
return this.geocode(q);
}
async geocode (q) {
const openCageKey = await this.rs.apiKeys.get('opencage').then(c => c.token);
const response = await fetch(
`https://api.opencagedata.com/geocode/v1/json?key=${openCageKey}&q=${q}&no_record=1`
);
return response.json();
}
}

46
modules/profile.mjs Normal file
View File

@@ -0,0 +1,46 @@
import { showElement, updateHTML, renderImage } from './dom-helpers.mjs';
function formattedCoordinates (geo) {
return `Latitude: ${geo.geometry.coordinates[1]}<br>` +
`Longitude: ${geo.geometry.coordinates[0]}<br>`;
}
function formattedLocation (geo) {
return `${geo.city || geo.state}, ${geo.country}`;
}
async function renderPublicProfile (geo) {
showElement('.profile.public');
updateHTML('.profile.public .coords', formattedCoordinates(geo));
updateHTML('.profile.public .formatted', formattedLocation(geo));
}
async function initializeProfileUpdates(remoteStorage, data) {
const privateClient = remoteStorage.scope('/profile/');
const publicClient = remoteStorage.scope('/public/profile/');
const profileUrl = await publicClient.getItemURL('current-location');
const imageUrl = await publicClient.getItemURL('current-location.png');
updateHTML('.profile.public .link', `<a href="${profileUrl}">Public URL</a>`);
await publicClient.getObject('current-location').then(async res => {
if (res) {
renderPublicProfile(res);
renderImage('.profile.public .map', imageUrl, '260x100');
}
})
document.querySelector('.current-city button.publish').addEventListener('click', async () => {
const content = JSON.stringify(data.currentCity.geoJSON);
const mapImageData = data.currentCity.imageArrayBuffer;
publicClient.storeFile('application/geo+json', 'current-location', content)
.then(renderPublicProfile(data.currentCity.geoJSON));
publicClient.storeFile('image/png', 'current-location.png', mapImageData)
.then(() => {
renderImage('.profile.public .map', `${imageUrl}?${new Date().getTime()}`, '260x100');
});
})
}
export default initializeProfileUpdates;

View File

@@ -0,0 +1,23 @@
const ApiKeys = { name: 'api-keys', builder: function (privateClient, publicClient) {
privateClient.declareType('credentials', {
// TODO add schema
});
return {
exports: {
set (serviceName, credentials = {}) {
return privateClient.storeObject('credentials', serviceName, credentials);
},
get (serviceName) {
return privateClient.getObject(serviceName);
},
remove (serviceName) {
return privateClient.remove(serviceName);
}
}
}
}};
export default ApiKeys;

32
modules/settings.mjs Normal file
View File

@@ -0,0 +1,32 @@
async function initializeSettings(remoteStorage) {
//
// API Keys (remoteStorage)
//
['opencage', 'mapbox'].forEach(async service => {
let inputEl = document.querySelector(`input.api-key.${service}`);
await remoteStorage.apiKeys.get(service).then(credentials => {
if (credentials) inputEl.value = credentials.token;
})
inputEl.addEventListener('change', e => {
if (e.target.value.length > 0) {
remoteStorage.apiKeys.set(service, { token: e.target.value });
} else {
remoteStorage.apiKeys.remove(service);
}
})
});
//
// Map settings (localStorage)
//
const zoomFactorSelectEl = document.querySelector('.settings .map-zoom-factor');
const zoomFactor = localStorage.getItem('rs-location:map-zoom-factor');
if (zoomFactor) zoomFactorSelectEl.value = zoomFactor;
zoomFactorSelectEl.addEventListener('change', e => {
localStorage.setItem('rs-location:map-zoom-factor', e.target.value);
});
}
export default initializeSettings;