initial commit
|
@ -0,0 +1,298 @@
|
||||||
|
import document from "document";
|
||||||
|
import clock from "clock";
|
||||||
|
import * as messaging from "messaging";
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { HeartRateSensor } from "heart-rate";
|
||||||
|
import { today } from "user-activity";
|
||||||
|
import { goals } from "user-activity";
|
||||||
|
import { vibration } from "haptics";
|
||||||
|
import { display } from "display";
|
||||||
|
import { preferences } from "user-settings";
|
||||||
|
import { me as device } from "device";
|
||||||
|
|
||||||
|
if (!device.screen) device.screen = { width: 348, height: 250 };
|
||||||
|
|
||||||
|
const placeholder = '···';
|
||||||
|
|
||||||
|
const colorSchemes = {
|
||||||
|
blues: ["#343375", "#6795b1"],
|
||||||
|
aurora: ["#320c72", "#24c2bf"],
|
||||||
|
roast: ["#ba8867", "#3c2710"],
|
||||||
|
blush: ["#d09593", "#c71d6f"],
|
||||||
|
ponyhair: ["#e9438b", "#9acccd"],
|
||||||
|
lime: ["#dde170", "#06a33e"],
|
||||||
|
dawn: ["#3b93c5", "#9f59a9"],
|
||||||
|
peach: ["#fcbd95", "#f795a4"],
|
||||||
|
violet: ["#9d25eb", "#4e6cc3"],
|
||||||
|
}
|
||||||
|
|
||||||
|
const weekdays = [
|
||||||
|
'Sun',
|
||||||
|
'Mon',
|
||||||
|
'Tue',
|
||||||
|
'Wed',
|
||||||
|
'Thu',
|
||||||
|
'Fri',
|
||||||
|
'Sat'
|
||||||
|
];
|
||||||
|
|
||||||
|
let progress = 0;
|
||||||
|
let progressXPos = 1;
|
||||||
|
|
||||||
|
let progressEl = document.getElementById('progress');
|
||||||
|
let timeEl = document.getElementById('time');
|
||||||
|
let dateEl = document.getElementById('date');
|
||||||
|
let hrEl = document.getElementById('hr');
|
||||||
|
let heartEl = document.getElementById('heartbeat');
|
||||||
|
let textElements = document.getElementsByClassName('text');
|
||||||
|
|
||||||
|
let textOffset = 20;
|
||||||
|
let hrOffset = 42;
|
||||||
|
|
||||||
|
let hrm = new HeartRateSensor;
|
||||||
|
let hrTimer;
|
||||||
|
|
||||||
|
var colorDef = [
|
||||||
|
colorSchemes['violet'][0],
|
||||||
|
colorSchemes['violet'][1]
|
||||||
|
];
|
||||||
|
|
||||||
|
var storedColorDef;
|
||||||
|
var fileSuccess = true;
|
||||||
|
console.log('reading color def');
|
||||||
|
try {
|
||||||
|
storedColorDef = fs.readFileSync("colordef.txt", "cbor");
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
fileSuccess = false;
|
||||||
|
console.log('color def not found');
|
||||||
|
}
|
||||||
|
if (fileSuccess) {
|
||||||
|
colorDef = storedColorDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
hrEl.text = placeholder;
|
||||||
|
|
||||||
|
function zeroPad(i) {
|
||||||
|
if (i < 10) {
|
||||||
|
i = "0" + i;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateClock() {
|
||||||
|
let currDate = new Date();
|
||||||
|
let hours = currDate.getHours();
|
||||||
|
let displayHours = hours;
|
||||||
|
if (preferences.clockDisplay === '12h') {
|
||||||
|
displayHours = displayHours % 12;
|
||||||
|
displayHours = displayHours ? displayHours : 12;
|
||||||
|
}
|
||||||
|
let minutes = zeroPad(currDate.getMinutes());
|
||||||
|
let day = currDate.getDate();
|
||||||
|
//let month = currDate.getMonth()+1;
|
||||||
|
let weekday = weekdays[currDate.getDay()];
|
||||||
|
|
||||||
|
let timeString = `${displayHours}:${minutes}`;
|
||||||
|
timeEl.text = timeString;
|
||||||
|
let dateString = `${weekday} ${day}`;
|
||||||
|
dateEl.text = dateString;
|
||||||
|
|
||||||
|
updateProgress();
|
||||||
|
progressEl.width = progressXPos;
|
||||||
|
|
||||||
|
if (progress <= 0.5) {
|
||||||
|
for(let i=0; i < textElements.length; i++) {
|
||||||
|
textElements[i].x = progressXPos + textOffset;
|
||||||
|
textElements[i].textAnchor = 'start';
|
||||||
|
}
|
||||||
|
heartEl.x = progressXPos + textOffset - 8;
|
||||||
|
hrEl.x = progressXPos + textOffset + hrOffset;
|
||||||
|
hrEl.textAnchor = 'start';
|
||||||
|
} else {
|
||||||
|
for(let i=0; i < textElements.length; i++) {
|
||||||
|
textElements[i].x = progressXPos - textOffset;
|
||||||
|
textElements[i].textAnchor = 'end';
|
||||||
|
}
|
||||||
|
heartEl.x = progressXPos - textOffset - 38;
|
||||||
|
hrEl.x = progressXPos - textOffset - hrOffset + 4;
|
||||||
|
hrEl.textAnchor = 'end';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateProgress() {
|
||||||
|
let steps = (today.adjusted.steps || null);
|
||||||
|
if (steps !== null) {
|
||||||
|
let stepGoal = (goals.steps || 0);
|
||||||
|
progress = Math.min(steps/stepGoal, 1);
|
||||||
|
progressXPos = Math.max(device.screen.width*progress, 10);
|
||||||
|
} else {
|
||||||
|
progress = 1;
|
||||||
|
progressXPos = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateColor() {
|
||||||
|
progressEl.gradient.colors.c1 = colorDef[0];
|
||||||
|
progressEl.gradient.colors.c2 = colorDef[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
hrm.onreading = () => {
|
||||||
|
if (display.on) {
|
||||||
|
let heartRate = (hrm.heartRate || placeholder);
|
||||||
|
hrEl.text = heartRate;
|
||||||
|
}
|
||||||
|
clearTimeout(hrTimer);
|
||||||
|
hrTimer = setTimeout(() => {
|
||||||
|
hrEl.text = placeholder;
|
||||||
|
}, 5000);
|
||||||
|
hrm.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
clock.granularity = "minutes";
|
||||||
|
clock.ontick = () => updateClock();
|
||||||
|
updateColor();
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
hrm.start();
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
messaging.peerSocket.onmessage = e => {
|
||||||
|
console.log("Message received -> "+e.data.key+": "+e.data.newValue);
|
||||||
|
display.poke();
|
||||||
|
vibration.start("bump");
|
||||||
|
switch (e.data.key) {
|
||||||
|
case 'progresscolor':
|
||||||
|
colorDef[0] = colorSchemes[e.data.newValue][0];
|
||||||
|
colorDef[1] = colorSchemes[e.data.newValue][1];
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
updateColor();
|
||||||
|
updateClock();
|
||||||
|
fs.writeFileSync("colordef.txt", colorDef, "cbor");
|
||||||
|
}
|
||||||
|
|
||||||
|
messaging.peerSocket.onopen = () => {
|
||||||
|
console.log("Clockface opened socket");
|
||||||
|
};
|
||||||
|
|
||||||
|
messaging.peerSocket.close = () => {
|
||||||
|
console.log("Clockface closed socket");
|
||||||
|
};
|
||||||
|
|
||||||
|
messaging.peerSocket.onerror = (err) => {
|
||||||
|
console.log("Clockface socket error: " + err.code + " - " + err.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function addcommas(nStr) {
|
||||||
|
if (nStr < 1000) { return nStr; }
|
||||||
|
nStr += '';
|
||||||
|
let x = nStr.split('.');
|
||||||
|
let x1 = x[0];
|
||||||
|
let x2 = x.length > 1 ? '.' + x[1] : '';
|
||||||
|
let rgx = /(\d+)(\d{3})/;
|
||||||
|
while (rgx.test(x1)) {
|
||||||
|
x1 = x1.replace(rgx, '$1' + ',' + '$2');
|
||||||
|
}
|
||||||
|
return x1 + x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getActivityNumber(activity) {
|
||||||
|
let values = {raw: 0, display: 0};
|
||||||
|
|
||||||
|
switch (activity) {
|
||||||
|
case 'steps':
|
||||||
|
values.raw = (today.adjusted.steps || 0);
|
||||||
|
values.display = addcommas(values.raw);
|
||||||
|
break;
|
||||||
|
case 'cal':
|
||||||
|
values.raw = (today.adjusted.calories || 0);
|
||||||
|
values.display = addcommas(values.raw);
|
||||||
|
break;
|
||||||
|
case 'dist':
|
||||||
|
values.raw = (today.adjusted.distance || 0);
|
||||||
|
values.display = (Math.round(values.raw/10)/100 || 0);
|
||||||
|
break;
|
||||||
|
case 'elev':
|
||||||
|
values.raw = values.display = (today.adjusted.elevationGain || 0);
|
||||||
|
break;
|
||||||
|
case 'actmin':
|
||||||
|
values.raw = (today.adjusted.activeMinutes || 0);
|
||||||
|
values.display = addcommas(values.raw);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getActivityText(activity) {
|
||||||
|
let label = placeholder;
|
||||||
|
switch (activity) {
|
||||||
|
case 'hr':
|
||||||
|
label = hrLabel;
|
||||||
|
break;
|
||||||
|
case 'steps':
|
||||||
|
case 'cal':
|
||||||
|
case 'actmin':
|
||||||
|
case 'dist':
|
||||||
|
case 'elev':
|
||||||
|
label = getActivityNumber(activity).display;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let touchArea = document.getElementById('touchArea');
|
||||||
|
let overlay = document.getElementById('overlay');
|
||||||
|
let healthTextInstances = document.getElementsByClassName('healthTextInstance');
|
||||||
|
let timeElementsNum = timeElements.length;
|
||||||
|
|
||||||
|
let hasOverlay = false;
|
||||||
|
let overlayTimer;
|
||||||
|
|
||||||
|
touchArea.onclick = (e) => {
|
||||||
|
if (hasOverlay == false) {
|
||||||
|
vibration.start("bump");
|
||||||
|
addOverlay();
|
||||||
|
} else {
|
||||||
|
removeOverlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateOverlay() {
|
||||||
|
document.getElementById('stepsText').getElementById('healthTextLabel').text = getActivityText('steps');
|
||||||
|
document.getElementById('calText').getElementById('healthTextLabel').text = getActivityText('cal');
|
||||||
|
document.getElementById('distText').getElementById('healthTextLabel').text = getActivityText('dist');
|
||||||
|
document.getElementById('elevText').getElementById('healthTextLabel').text = getActivityText('elev');
|
||||||
|
document.getElementById('actminText').getElementById('healthTextLabel').text = getActivityText('actmin');
|
||||||
|
}
|
||||||
|
|
||||||
|
function addOverlay() {
|
||||||
|
updateOverlay();
|
||||||
|
overlay.style.display = 'inline';
|
||||||
|
hasOverlay = true;
|
||||||
|
overlayTimer = setTimeout(() => {
|
||||||
|
removeOverlay();
|
||||||
|
},6000);
|
||||||
|
document.getElementById('overlayShadeInstance').animate('enable');
|
||||||
|
for(let i in healthTextInstances) {
|
||||||
|
setTimeout(() => {
|
||||||
|
healthTextInstances[i].animate('enable');
|
||||||
|
}, 200+i*100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeOverlay() {
|
||||||
|
clearTimeout(overlayTimer);
|
||||||
|
document.getElementById('overlayShadeInstance').animate('disable');
|
||||||
|
for(var i = 0; i < healthTextInstances.length; i++) {
|
||||||
|
healthTextInstances[i].animate('disable');
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
overlay.style.display = 'none';
|
||||||
|
}, 100);
|
||||||
|
hasOverlay = false;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
import * as messaging from "messaging";
|
||||||
|
import { settingsStorage } from "settings";
|
||||||
|
|
||||||
|
//console.log("Companion Started");
|
||||||
|
|
||||||
|
messaging.peerSocket.onopen = () => {
|
||||||
|
};
|
||||||
|
|
||||||
|
messaging.peerSocket.close = () => {
|
||||||
|
};
|
||||||
|
|
||||||
|
settingsStorage.onchange = evt => {
|
||||||
|
let data = {}
|
||||||
|
switch(evt.key) {
|
||||||
|
case 'progresscolor':
|
||||||
|
data = {
|
||||||
|
key: evt.key,
|
||||||
|
newValue: JSON.parse(evt.newValue).values[0].value
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
data = {
|
||||||
|
key: evt.key,
|
||||||
|
newValue: evt.newValue
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendVal(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
function sendVal(data) {
|
||||||
|
if (messaging.peerSocket.readyState === messaging.peerSocket.OPEN) {
|
||||||
|
messaging.peerSocket.send(data);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"fitbit": {
|
||||||
|
"appUUID": "8dc25404-83b5-4c54-b526-0358433453ff",
|
||||||
|
"appType": "clockface",
|
||||||
|
"appDisplayName": "Progress",
|
||||||
|
"iconFile": "resources/icon.png",
|
||||||
|
"wipeColor": "#607d8b",
|
||||||
|
"requestedPermissions": [
|
||||||
|
"access_heart_rate",
|
||||||
|
"access_activity"
|
||||||
|
],
|
||||||
|
"buildTargets": [
|
||||||
|
"higgs",
|
||||||
|
"meson"
|
||||||
|
],
|
||||||
|
"i18n": {
|
||||||
|
"en": {
|
||||||
|
"name": "Progress"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 342 B |
After Width: | Height: | Size: 413 B |
After Width: | Height: | Size: 574 B |
After Width: | Height: | Size: 367 B |
After Width: | Height: | Size: 258 B |
After Width: | Height: | Size: 446 B |
|
@ -0,0 +1,39 @@
|
||||||
|
<svg>
|
||||||
|
<gradientRect x="0" y="80%" width="100%" height="40%" id="background"
|
||||||
|
gradient-type="linear"
|
||||||
|
gradient-x1="0" gradient-y1="0"
|
||||||
|
gradient-x2="0" gradient-y2="100%"
|
||||||
|
gradient-color1="black" gradient-color2="#444444"
|
||||||
|
/>
|
||||||
|
<gradientRect x="0" y="0" width="1" height="100%" id="progress"
|
||||||
|
gradient-type="linear"
|
||||||
|
gradient-x1="0" gradient-y1="20"
|
||||||
|
gradient-x2="0" gradient-y2="100%-20"
|
||||||
|
gradient-color1="black" gradient-color2="black"
|
||||||
|
/>
|
||||||
|
<image href="img/dithernoise.png" id="fakedither" opacity="0.1" fill="black" />
|
||||||
|
<text class="text" id="time" fill="white" x="20" y="70" />
|
||||||
|
<text class="text" id="date" fill="white" x="20" y="110" />
|
||||||
|
<text id="hr" fill="white" x="20" y="100%-22" />
|
||||||
|
<use href="#heart" id="heartbeat" x="20" y="100%-34" />
|
||||||
|
|
||||||
|
<g id="overlay">
|
||||||
|
<use href="#overlayShade" id="overlayShadeInstance" />
|
||||||
|
<use href="#healthText" x="35%" y="22%" class="healthTextInstance" id="stepsText">
|
||||||
|
<set href="healthTextIcon" attributeName="href" to="img/icon-steps.png" />
|
||||||
|
</use>
|
||||||
|
<use href="#healthText" x="35%" y="47%" class="healthTextInstance" id="calText">
|
||||||
|
<set href="healthTextIcon" attributeName="href" to="img/icon-cal.png" />
|
||||||
|
</use>
|
||||||
|
<use href="#healthText" x="35%" y="72%" class="healthTextInstance" id="distText">
|
||||||
|
<set href="healthTextIcon" attributeName="href" to="img/icon-dist.png" />
|
||||||
|
</use>
|
||||||
|
<use href="#healthText" x="76%" y="22%" class="healthTextInstance" id="elevText">
|
||||||
|
<set href="healthTextIcon" attributeName="href" to="img/icon-elev.png" />
|
||||||
|
</use>
|
||||||
|
<use href="#healthText" x="76%" y="47%" class="healthTextInstance" id="actminText">
|
||||||
|
<set href="healthTextIcon" attributeName="href" to="img/icon-actmin.png" />
|
||||||
|
</use>
|
||||||
|
</g>
|
||||||
|
<rect x="0" y="0" width="100%" height="100%" opacity="0" id="touchArea" pointer-events="visible" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1,35 @@
|
||||||
|
.text {
|
||||||
|
font-family: Colfax-Regular;
|
||||||
|
}
|
||||||
|
|
||||||
|
#date {
|
||||||
|
text-length: 8;
|
||||||
|
font-size: 33;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hr {
|
||||||
|
text-length: 6;
|
||||||
|
font-size: 28;
|
||||||
|
}
|
||||||
|
|
||||||
|
#time {
|
||||||
|
font-family: Fabrikat-Regular;
|
||||||
|
font-size: 60;
|
||||||
|
text-length: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlayShadeColor {
|
||||||
|
fill: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.healthTextLabel {
|
||||||
|
font-size: 28;
|
||||||
|
font-family: Fabrikat-Regular;
|
||||||
|
text-length: 8;
|
||||||
|
text-anchor: end;
|
||||||
|
fill: white;
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<svg>
|
||||||
|
<defs>
|
||||||
|
<link rel="stylesheet" href="styles.css" />
|
||||||
|
<link rel="import" href="/mnt/sysassets/widgets_common.gui" />
|
||||||
|
|
||||||
|
<symbol id="overlayShade">
|
||||||
|
<rect id="overlayShadeColor" width="100%" height="100%" opacity="0.85" />
|
||||||
|
<animate attributeName="opacity" begin="enable" from="0" to="1" dur="0.25" final="freeze" />
|
||||||
|
<animate attributeName="opacity" begin="disable" from="1" to="0" dur="0.1" final="freeze" />
|
||||||
|
</symbol>
|
||||||
|
|
||||||
|
<symbol id="heart">
|
||||||
|
<g transform="scale(0.95),translate(26, 3)" id="healthTextHrIcon">
|
||||||
|
<animateTransform attributeType="scale" begin="load" from="0.95" to="0.85" dur="0.9" final="restore" repeatCount="indefinite" easing="ease-out"/>
|
||||||
|
<svg width="27" height="27">
|
||||||
|
<circle cx="-24%" cy="-24%" r="26%" fill="white" />
|
||||||
|
<circle cx="24%" cy="-24%" r="26%" fill="white" />
|
||||||
|
<g transform="translate(0, 40%), rotate(-135)">
|
||||||
|
<rect x="0" y="0" width="62%" height="38%" fill="white" />
|
||||||
|
<rect x="0" y="0" width="38%" height="62%" fill="white" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</g>
|
||||||
|
</symbol>
|
||||||
|
|
||||||
|
<symbol id="healthText">
|
||||||
|
<g opacity="0">
|
||||||
|
<text x="0" y="14" class="healthTextLabel" id="healthTextLabel" />
|
||||||
|
<image x="11" y="-12" width="30" height="30" href="" fill="white" id="healthTextIcon" />
|
||||||
|
<animate attributeName="opacity" begin="enable" from="0" to="1" dur="0.25" final="freeze" />
|
||||||
|
<animateTransform attributeType="translate" begin="enable" from="0, -10" to="0, 0" dur="0.25" final="freeze" easing="ease-out" />
|
||||||
|
<animate attributeName="opacity" begin="disable" from="1" to="0" dur="0.1" final="freeze" />
|
||||||
|
<animateTransform attributeType="translate" begin="disable" from="0, 0" to="0, 10" dur="0.1" final="freeze" easing="ease-out" />
|
||||||
|
</g>
|
||||||
|
</symbol>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,34 @@
|
||||||
|
function Progress(props) {
|
||||||
|
return (
|
||||||
|
<Page>
|
||||||
|
<Section
|
||||||
|
title={<Text bold>Color Settings</Text>}>
|
||||||
|
<Select
|
||||||
|
label={`Progress Color`}
|
||||||
|
settingsKey="progresscolor"
|
||||||
|
options={[
|
||||||
|
{name:"Violet", value:"violet", icon:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAMAAAANIilAAAAAe1BMVEWdJeucJuubJ+qZKOmYKuiWK+eVLOeTLuaRL+WQMeWOMuONM+OLNeKKNuGIN+GHOeCFO9+CPd2BPt1+Qdt/QNx8Qtt5Rdl7RNl4Rth2SNdzStZwTdRvT9NqU9FnVc9oVNFiWc1fXMxcX8pbYMlWZMdTZ8VSaMVPa8NObMPgCFu1AAABPUlEQVR4AeTLxQECURAE0cJ9fb/lnyeWAVNH3kifmn+0EdgK7AT2AgeBo8BJ4CxwEbgK3ATuAg+BTqAXGATe14fLo8A0zWN0WOZ5Xdc5MjPfeFvH9edjjUrrSsqlrMGhCK5cayuvYsdAN0IYhqH+jImsJXdJB///hUssqRq3wQGVtGdXTkVccVeYpojk4/rBNAAmEQ6Sg1w6E2QAfEpQQrfKtcpM6WWhSJRLIHG7eFBqraXMRfkYfVIqyO486/a36bdZUAOddYPQh0mjarajLtpNjpNAB/jH8uP5fJhSSjKNeajAwCrvP1APmXL6U/HFs2wvsJN4Vm0HbsF+4TSbTN9dgbnTCQfrd07MDf2LoU+9dAquwt/SfA94a04xU1zneAC30QbA10h5eaUtjT4BlgHGyuu6jpSDofLNB74BsSM6TDJPgIYAAAAASUVORK5CYII="},
|
||||||
|
{name:"Peach", value:"peach", icon:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAMAAAANIilAAAAAM1BMVEX8vZX8u5b8uZb7uZb7t5f7tJj7sZn6rpr6q5v5p535pJ74nqD6qZz5oZ/4m6H3l6P3laQKzTpRAAABVUlEQVR4AeWOh3IDIQxE9zpw9f+/NsvazCidkp63QkLje4zxL+la0qGvTtdXA/QNtMnDOEyVGTFOnJXBKFuntCZMo8xSJIFuNVCfbyktqE+x1HK7irLQUMvrKhhtKgq/B9uicLJyo88xL8t9U8s9krA08MGyy41k53QTWjLjFjhxt+MlDzlYXD1wTbJnIqFK9rECszpWCdg8cdEm0vMDqiJoZeWfAGo+hCjHrEWJssIl3GRTb88V0SReZlkcQlgp8s5pfll5ntbTHwICTeo0vf1MeVK2KQg79Wg7Y8domjy+6iCsCk3tahqMxZlLKuwUY8lOunkgJW32Kcqy7eNP7xbzhJMs19t/lb56B6SL9EIk19EuH4xIM22H9icc4uaAw6CnIprvAXV9XY5kcdbIpzSNCpka0aR/KnkgqRpqmjrvgbOG75cv0iQbTnKdeQ9ekiv5rfIDvep6F+lQq34AAAAASUVORK5CYII="},
|
||||||
|
{name:"Dawn", value:"dawn", icon:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAMAAAANIilAAAAAaVBMVEU7k8U9kcQ/j8NDjsJHi8FFjcJKicBPh79Shb5Wgr1YgbxagLxcf7xgfbpmeblpd7hoeLhrdrdtdbZvdLZxc7VzcrV1cLR5brOEZ7B9bLKAarGGZq+MY66UXqybWqmOYq2SYKyXXaufWal+cdL0AAACCElEQVR4AeyM0ZbDIAhEqXWJsYvE7v//6w5KT3zY7GnMay8wjoYJfTjJLQT0FDcKF7gWvt9DnMxG+ooxxDkCmXIMPJMmRNEMPQsz8QWIlwvhZUm88prOw4ncrHx2UD284raea1QiBBMMrtkE856CRO3Ir4F0Bf94h/LfYGfnyNMjz0Pf+SE4MTKUIcMMbj+FRCTblNxGWgPzsNoe3XkpXoo9WdjBay/fVds7qP5HspSPyivtDnpYogiXIuit70tFdadq2qr3WNp2CsJbKVrsXtW0O3zEFXh0xPMIbwDRrUV30VrHmNvxAUObDiAwUtGj9Vbxk6qh1Q9bexet9Kzz0M/zt7Qx0JEQhIFof4GkR4sL7t7+/0fedCQxJOIZfVMnBPqipp+7sqrmnJOpGgqfJT3BkxFuSdacMlDakTO4EVCXvKFmioA0DY3+6xRHyqZaKLLmdJVQNlLsAE9uJ3jqstslxk2XsgArxRZc9+lhDYnar1UW2Lgti/XX63FZgBvkXfzPYW+yR1gd8wEbmtUxOdqcqwMveW34HZ7JtdvVIw25ygr5HdTaOHDXy3F5k9ocauXVUNNEUQatNszBymyQJp/2aQFtXA3ydPhaheIb3xrDBxa/2fRX+Q0PFm1c1VHlNx72J8iQaMZX12HrUEc2qvRDY/NxchoOzqF8l2fy95n8fSZ/b8sP7D/AWuY0svXUEQAAAABJRU5ErkJggg=="},
|
||||||
|
{name:"Lime", value:"lime", icon:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAIAAAC1nk4lAAAAi0lEQVR4AWK8+7AA0K5dGEEUwlAUzUr/BX+0AhhZDXNeBReJJ7LpHkuBBv1sY+SDrimhu5veCHTkgy69x1fke0S4aX/6qJtuKV1eztyji4gMUT7Ne/xxjeim1Yg7gY6U+bTvAfqwLE+NCNqfluXpe7xf/rQ54lr+9NDLk3vo5blp0PoeIqJtMdDHQU8F5JLHx3oKRgAAAABJRU5ErkJggg=="},
|
||||||
|
{name:"Blush", value:"blush", icon:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAMAAAANIilAAAAAkFBMVEXQlZPQk5LQkZLPj5HPjJDPipDPh4/PhY7Pg43OgY3OfozOfIvOeYvOdYrNc4jNcIjNbofNaobNbIfNZ4XMYIPMZYXMYoTMXoLMXILMWYHLV4DLU3/LTn3KS33KSXzKRXvKQnrJPXnKQHrJO3jJOXfJN3fJNHbJMnXIMHXILnTIK3PIKXLHInHIJHHHIHDHHW+2HUOCAAAAyklEQVR4Ae3QoRLbUAxE0Xv3CRcVl/b/P9BWQWcCiuJFnUnOyhJa4McHUnrz/5a/5W852Mcf9AK9UWoRAEEef5Pt27MEAO7nd/Lv0519+ybneGRe4e1rvO9zM5fX/A1vX/x5qOXQG0U61yitE+mNuC7VBGCthhHqCRIDzyf4i15AEHi+X//suo/3IMACPt6j64oUO8E2OxtqE6lFejHnMFWOv11Zq0QEu4z0grScvg2Bvj1Z9tw0dpZwdW0nwCH1a0vHkb4dAD6r/Ae5WZ00FhkppAAAAABJRU5ErkJggg=="},
|
||||||
|
{name:"Roast", value:"roast", icon:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAIAAAC1nk4lAAAAeUlEQVR4AWLc1ZEOaNcOMAAGghiKrur9b9xJT7CFVgkvJ4jvG7F2teVY2yit9DlJX+lrppD0b6WRDj224XSlHkGa0+400py2p9+G006elYe0O400p+1ppG0P7x6ctvKQRtr1sKc5jXTs6YdwOkHa9nCnfbxSWulPcwPno51T78u2kwAAAABJRU5ErkJggg=="},
|
||||||
|
{name:"Aurora", value:"aurora", icon:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAIAAAC1nk4lAAAAdklEQVR4AWI04ikCtGsHGADDQBBFk7H3v3J6gwDaDm9P8I2H0qy2yyo80aIvN2t2X/SZFC5dGZ1KHruTh2immRbNNB6iTyp5MG3pi+lfL820pZlm2ldeWnmIZppp0Uzj4Z8L00wz/eoxzTTTlmY6THt4JfrjewADWBCF1g0MKwAAAABJRU5ErkJggg=="},
|
||||||
|
{name:"Blues", value:"blues", icon:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAIAAAC1nk4lAAAAm0lEQVR4AWI0MS4FtGMHGhTDMBiF26zv/8Z3rgl9gMKS+YItOjj7HVEZ3SpKUoE+L9BrxuwIHZI+KdCgQc/S0Oa0pEFzWtLvM3Na0qBHR+j4mtPu05w28uhxlrQ5zelZAJrTkjannxen6WE/zWlXU9CcHl/SA7T9dMT1QDd7Jvv9u7Op38cVkUf5B/X7rJVH+1vxPtHX7urXRv8DwEBjUXkS1AoAAAAASUVORK5CYII="},
|
||||||
|
{name:"Pony Hair", value:"ponyhair", icon:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAMAAAANIilAAAAAllBMVEXpQ4vmRozkSI7jTI/iTpDgUZHeU5PdVpTcWJXaW5bYXpjWY5rUZpvXYZnSaJ3Ra57QbZ/OcKDMc6LJeKTGfafDgqnFgKjChavAiK2+i669ja+8kLC4lbO6krKyoLi2m7W3l7S0nbexormwpbqup7ysqr2rrL6qsL+mtcKossGkusSlt8Ogv8eivMadxcmbx8uaysyfwsjK80E8AAABkklEQVR4AeyLR2LFIBQDBfzqTnO7/0GD3JYJfmwzI9HBPzdRWq5WKMBoo8UoDSNTGTwLwOu5KeD5wvslR6sEjNBvAaiqLz2SXwZVAaibtqmaqhPYoNnozomL3Dbg+45wugn6Tg6GvrOXHZuNhZXirIVz9tR6Tlx5+1f43MF5ynjLkeWJ9b+Hr+DlFH4OG55Gz7B5iRhDiCESfzYvaUAkISkAU5SDeY7LEilZ8pPEUgDWRY5WxGD3oZLI1eCndDnQjRCEwQDc13CB7s5dXTd7yN7/5VaghstCJujX39aE/N479+YmHY0f4sA5bRv/CqejSeVX6PNoctu3ry0H77fMJbqtuR+c2jcvB3e8I96w8rY0/366QLunwYznwceMc3Kq/HhQtaDGpiNApO2ZMtS66agSAf1hxR4En/ufYp1yezDBFy9sUrcczTFiSGfZY9VewBfA97quwhqW4YHnU1ZJES6p62BEQAzLKK7lIOMgFFuQUPR3A2xb0ElC1V2uYmj6adKHCDHGdv+YlqstDoJ4waXyL1jfQHdkrnntAAAAAElFTkSuQmCC"},
|
||||||
|
]}
|
||||||
|
renderItem={
|
||||||
|
(option) =>
|
||||||
|
<TextImageRow
|
||||||
|
label={option.name}
|
||||||
|
icon={option.icon}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
onSelection={(selection) => console.log(selection)}
|
||||||
|
/>
|
||||||
|
</Section>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
registerSettingsPage(Progress);
|