Hello world
This commit is contained in:
28
modules/dom-helpers.mjs
Normal file
28
modules/dom-helpers.mjs
Normal 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
20
modules/geocode.mjs
Normal 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
46
modules/profile.mjs
Normal 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;
|
||||
23
modules/rs-module-api-keys.mjs
Normal file
23
modules/rs-module-api-keys.mjs
Normal 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
32
modules/settings.mjs
Normal 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;
|
||||
Reference in New Issue
Block a user