mirror of
https://github.com/microsoft/Web-Dev-For-Beginners.git
synced 2025-08-25 07:41:18 +02:00
folder names
This commit is contained in:
28
5-browser-extension/solution/README.md
Normal file
28
5-browser-extension/solution/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Carbon Trigger Browser Extension: Completed Code
|
||||
|
||||
Using tmrow's C02 Signal API to track electricity usage, build a browser extension so that you can have a reminder right in your browser about how heavy your region's electricity usage is. Using this extension ad hoc will help you to make judgement calls on your activities based on this information.
|
||||
|
||||

|
||||
|
||||
## Getting Started
|
||||
|
||||
You will need to have [npm](https://npmjs.com) installed. Download a copy of this code to a folder on your computer.
|
||||
|
||||
Install all the required packages:
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
Build the extension from webpack
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
To install on Edge, use the 'three dot' menu on the top right corner of the browser to find the Extensions panel. From there, select 'Load Unpacked' to load a new extension. Open the 'dist' folder at the prompt and the extension will load. To use it, you will need an API key for CO2 Signal's API ([get one here via email](https://www.co2signal.com/) - enter your email in the box on this page) and the [code for your region](http://api.electricitymap.org/v3/zones) corresponding to the [Electricity Map](https://www.electricitymap.org/map) (in Boston, for example, I use 'US-NEISO').
|
||||
|
||||

|
||||
|
||||
Once the API key and region is input into the extension interface, the colored dot in the browser extension bar should change to reflect your region's energy usage and give you a pointer on what energy-heavy activities would be appropriate for you to perform. The concept behind this 'dot' system was given to me by the [Energy Lollipop extension](https://energylollipop.com/) for California emissions.
|
||||
|
17
5-browser-extension/solution/dist/background.js
vendored
Normal file
17
5-browser-extension/solution/dist/background.js
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
|
||||
if (msg.action === 'updateIcon') {
|
||||
chrome.browserAction.setIcon({ imageData: drawIcon(msg.value) });
|
||||
}
|
||||
});
|
||||
//borrowed from energy lollipop extension, nice feature!
|
||||
function drawIcon(value) {
|
||||
let canvas = document.createElement('canvas');
|
||||
let context = canvas.getContext('2d');
|
||||
|
||||
context.beginPath();
|
||||
context.fillStyle = value.color;
|
||||
context.arc(100, 100, 50, 0, 2 * Math.PI);
|
||||
context.fill();
|
||||
|
||||
return context.getImageData(50, 50, 100, 100);
|
||||
}
|
BIN
5-browser-extension/solution/dist/images/plants-people.png
vendored
Normal file
BIN
5-browser-extension/solution/dist/images/plants-people.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 71 KiB |
44
5-browser-extension/solution/dist/index.html
vendored
Normal file
44
5-browser-extension/solution/dist/index.html
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>My Carbon Trigger</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
|
||||
<body class="container">
|
||||
<img alt="plants and people" src="images/plants-people.png" />
|
||||
<div>
|
||||
<h1>Welcome to Your Personal Carbon Trigger!</h1>
|
||||
</div>
|
||||
<form class="form-data" autocomplete="on">
|
||||
<div>
|
||||
<h2>New? Add your Information</h2>
|
||||
</div>
|
||||
<div>
|
||||
<label>Region Name</label>
|
||||
<input type="text" required class="region-name" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Your API Key from tmrow</label>
|
||||
<input type="text" required class="api-key" />
|
||||
</div>
|
||||
<button class="search-btn">Submit</button>
|
||||
</form>
|
||||
<div class="result">
|
||||
<div class="loading">loading...</div>
|
||||
<div class="errors"></div>
|
||||
<div class="data"></div>
|
||||
<div class="result-container">
|
||||
<p><strong>Region: </strong><span class="my-region"></span></p>
|
||||
<p><strong>Carbon Usage: </strong><span class="carbon-usage"></span></p>
|
||||
<p><strong>Fossil Fuel Percentage: </strong><span class="fossil-fuel"></span></p>
|
||||
</div>
|
||||
<button class="clear-btn">Change region</button>
|
||||
</div>
|
||||
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
0
5-browser-extension/solution/dist/main.js
vendored
Normal file
0
5-browser-extension/solution/dist/main.js
vendored
Normal file
12
5-browser-extension/solution/dist/manifest.json
vendored
Normal file
12
5-browser-extension/solution/dist/manifest.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "My Carbon Trigger",
|
||||
"version": "0.1.0",
|
||||
"permissions": ["<all_urls>"],
|
||||
"background": {
|
||||
"scripts": ["background.js"]
|
||||
},
|
||||
"browser_action": {
|
||||
"default_popup": "index.html"
|
||||
}
|
||||
}
|
143
5-browser-extension/solution/dist/styles.css
vendored
Normal file
143
5-browser-extension/solution/dist/styles.css
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
.container {
|
||||
margin: 1.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.result {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.clear-btn {
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/*basic css*/
|
||||
/* courtesy of: https://github.com/vladocar/Basic.css */
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:root {
|
||||
--sans: 1em/1.6 system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell,
|
||||
Droid Sans, Helvetica Neue, Fira Sans, sans-serif;
|
||||
--mono: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, 'Courier New', monospace;
|
||||
--c1: #0074d9;
|
||||
--c2: #eee;
|
||||
--c3: #fff;
|
||||
--c4: #000;
|
||||
--c5: #fff;
|
||||
--m1: 8px;
|
||||
--rc: 8px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--c2: #333;
|
||||
--c3: #1e1f20;
|
||||
--c4: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
/* General settings */
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font: var(--sans);
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
background-color: var(--c3);
|
||||
color: var(--c4);
|
||||
min-width: 300px;
|
||||
}
|
||||
img,
|
||||
iframe {
|
||||
border: none;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--c1);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--c1);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Headlines */
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
margin: 0.6em 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.5em;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.4em;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* Rounded Corners*/
|
||||
|
||||
input,
|
||||
button,
|
||||
img {
|
||||
border-radius: var(--rc);
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
/* Forms */
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font-size: 1em;
|
||||
color: var(--c4);
|
||||
background: var(--c2);
|
||||
border: 0;
|
||||
padding: 0.6em;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
button,
|
||||
input[type='submit'],
|
||||
input[type='reset'],
|
||||
input[type='button'] {
|
||||
-webkit-appearance: none;
|
||||
font-size: 1em;
|
||||
display: inline-block;
|
||||
color: var(--c5);
|
||||
background: var(--c1);
|
||||
border: 0;
|
||||
margin: 4px;
|
||||
padding: 0.6em;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
button:hover,
|
||||
button:focus,
|
||||
input:hover,
|
||||
textarea:hover,
|
||||
select:hover {
|
||||
opacity: 0.8;
|
||||
}
|
25
5-browser-extension/solution/package.json
Normal file
25
5-browser-extension/solution/package.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "carbon-trigger-extension",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"watch": "webpack --watch",
|
||||
"build": "webpack"
|
||||
},
|
||||
"keywords": [
|
||||
"chrome extension",
|
||||
"edge extension",
|
||||
"carbon usage tracker"
|
||||
],
|
||||
"author": "Jen Looper",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"webpack": "^4.44.1",
|
||||
"webpack-cli": "^3.3.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.19.2"
|
||||
}
|
||||
}
|
127
5-browser-extension/solution/src/index.js
Normal file
127
5-browser-extension/solution/src/index.js
Normal file
@@ -0,0 +1,127 @@
|
||||
import axios from './node_modules/axios';
|
||||
|
||||
// form fields
|
||||
const form = document.querySelector('.form-data');
|
||||
const region = document.querySelector('.region-name');
|
||||
const apiKey = document.querySelector('.api-key');
|
||||
|
||||
// results
|
||||
const errors = document.querySelector('.errors');
|
||||
const loading = document.querySelector('.loading');
|
||||
const results = document.querySelector('.result-container');
|
||||
const usage = document.querySelector('.carbon-usage');
|
||||
const fossilfuel = document.querySelector('.fossil-fuel');
|
||||
const myregion = document.querySelector('.my-region');
|
||||
const clearBtn = document.querySelector('.clear-btn');
|
||||
|
||||
calculateColor = async (value) => {
|
||||
let co2Scale = [0, 150, 600, 750, 800];
|
||||
let colors = ['#2AA364', '#F5EB4D', '#9E4229', '#381D02', '#381D02'];
|
||||
|
||||
let closestNum = co2Scale.sort((a, b) => {
|
||||
return Math.abs(a - value) - Math.abs(b - value);
|
||||
})[0];
|
||||
//console.log(value + ' is closest to ' + closestNum);
|
||||
let num = (element) => element > closestNum;
|
||||
let scaleIndex = co2Scale.findIndex(num);
|
||||
|
||||
let closestColor = colors[scaleIndex];
|
||||
//console.log(scaleIndex, closestColor);
|
||||
|
||||
chrome.runtime.sendMessage({ action: 'updateIcon', value: { color: closestColor } });
|
||||
};
|
||||
|
||||
const displayCarbonUsage = async (apiKey, region) => {
|
||||
try {
|
||||
await axios
|
||||
.get('https://api.co2signal.com/v1/latest', {
|
||||
params: {
|
||||
countryCode: region,
|
||||
},
|
||||
headers: {
|
||||
//please get your own token from CO2Signal https://www.co2signal.com/
|
||||
'auth-token': apiKey,
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
let CO2 = Math.floor(response.data.data.carbonIntensity);
|
||||
|
||||
calculateColor(CO2);
|
||||
|
||||
loading.style.display = 'none';
|
||||
form.style.display = 'none';
|
||||
myregion.textContent = region;
|
||||
usage.textContent =
|
||||
Math.round(response.data.data.carbonIntensity) + ' grams (grams C02 emitted per kilowatt hour)';
|
||||
fossilfuel.textContent =
|
||||
response.data.data.fossilFuelPercentage.toFixed(2) +
|
||||
'% (percentage of fossil fuels used to generate electricity)';
|
||||
results.style.display = 'block';
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
loading.style.display = 'none';
|
||||
results.style.display = 'none';
|
||||
errors.textContent = 'Sorry, we have no data for the region you have requested.';
|
||||
}
|
||||
};
|
||||
|
||||
// set up api key and region
|
||||
const setUpUser = async (apiKey, regionName) => {
|
||||
localStorage.setItem('apiKey', apiKey);
|
||||
localStorage.setItem('regionName', regionName);
|
||||
loading.style.display = 'block';
|
||||
errors.textContent = '';
|
||||
clearBtn.style.display = 'block';
|
||||
//make initial call
|
||||
displayCarbonUsage(apiKey, regionName);
|
||||
};
|
||||
|
||||
// handle form submission
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
setUpUser(apiKey.value, region.value);
|
||||
};
|
||||
|
||||
//initial checks
|
||||
const init = async () => {
|
||||
//if anything is in localStorage, pick it up
|
||||
const storedApiKey = localStorage.getItem('apiKey');
|
||||
const storedRegion = localStorage.getItem('regionName');
|
||||
|
||||
//set icon to be generic green
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'updateIcon',
|
||||
value: {
|
||||
color: 'green',
|
||||
},
|
||||
});
|
||||
|
||||
if (storedApiKey === null || storedRegion === null) {
|
||||
//if we don't have the keys, show the form
|
||||
form.style.display = 'block';
|
||||
results.style.display = 'none';
|
||||
loading.style.display = 'none';
|
||||
clearBtn.style.display = 'none';
|
||||
errors.textContent = '';
|
||||
} else {
|
||||
//if we have saved keys/regions in localStorage, show results when they load
|
||||
results.style.display = 'none';
|
||||
form.style.display = 'none';
|
||||
displayCarbonUsage(storedApiKey, storedRegion);
|
||||
clearBtn.style.display = 'block';
|
||||
}
|
||||
};
|
||||
|
||||
const reset = async (e) => {
|
||||
e.preventDefault();
|
||||
//clear local storage for region only
|
||||
localStorage.removeItem('regionName');
|
||||
init();
|
||||
};
|
||||
|
||||
form.addEventListener('submit', (e) => handleSubmit(e));
|
||||
clearBtn.addEventListener('click', (e) => reset(e));
|
||||
|
||||
//start app
|
||||
init();
|
28
5-browser-extension/solution/translation/README.es.md
Normal file
28
5-browser-extension/solution/translation/README.es.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Extensión del navegador Carbon Trigger: Código completo
|
||||
|
||||
Usando la API de señal C02 de tmrow para rastrear el uso de electricidad, cree una extensión de navegador para que pueda tener un recordatorio directamente en su navegador sobre el consumo de electricidad de su región. El uso de esta extensión ad hoc le ayudará a tomar decisiones sobre sus actividades basándose en esta información.
|
||||
|
||||

|
||||
|
||||
## Empezando
|
||||
|
||||
Deberá tener [npm](https://npmjs.com) instalado. Descargue una copia de este código en una carpeta de su computadora.
|
||||
|
||||
Instale todos los paquetes necesarios:
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
Construye la extensión desde webpack:
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
Para instalar en Edge, use el menú de 'tres puntos' en la esquina superior derecha del navegador para encontrar el panel Extensiones. Desde allí, seleccione 'Cargar desempaquetado' para cargar una nueva extensión. Abra la carpeta 'dist' cuando se le solicite y se cargará la extensión. Para usarlo, necesitará una clave API para la API de CO2 Signal ([obtenga una aquí por correo electrónico](https://www.co2signal.com/) - ingrese su correo electrónico en el cuadro de esta página) y el [código para su región](http://api.electricitymap.org/v3/zones) correspondiente al [Mapa de electricidad](https://www.electricitymap.org/map) (en Boston, por ejemplo, utilizo 'US- NEISO').
|
||||
|
||||

|
||||
|
||||
Una vez que se ingresa la clave API y la región en la interfaz de extensión, el punto de color en la barra de extensión del navegador debe cambiar para reflejar el uso de energía de su región y darle un indicador sobre las actividades de alto consumo de energía que serían apropiadas para usted. El concepto detrás de este sistema de "puntos" me lo dio la [extensión Energy Lollipop](https://energylollipop.com/) para las emisiones de California.
|
||||
|
Reference in New Issue
Block a user