@vixoniccom/aqi 0.0.1-dev.4 → 0.0.1-dev.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build.zip CHANGED
Binary file
@@ -1,41 +1,23 @@
1
- import {
2
- Label,
3
- SelectAssetKna,
4
- SelectInput,
5
- TextFormat,
6
- TextInput,
7
- } from '@vixoniccom/modules'
1
+ import { Label, NumberInput, SelectAssetKna, TextFormat, TextInput } from '@vixoniccom/modules'
8
2
 
9
3
  export const appeareanceInputs = [
10
4
  new Label({ label: 'General' }),
11
- new TextInput({
12
- id: 'padding',
13
- label: 'Márgenes',
14
- required: false,
15
- description:
16
- 'CSS para mover la tarjeta. El formato es arriba/derecha/abajo/izquieda',
17
- }),
18
- new SelectAssetKna({
19
- id: 'backgroundImage',
20
- label: 'Fondo',
21
- required: false,
22
- extensions: ['jpg', 'png'],
23
- }),
5
+ new SelectAssetKna({ id: 'backgroundImage', label: 'Fondo', required: false, extensions: ['jpg', 'png'] }),
24
6
 
25
7
  new Label({ label: 'Diseño de la tarjeta' }),
26
- new TextInput({
27
- id: 'cardWidth',
28
- label: 'Ancho',
29
- required: false,
30
- description: 'Ancho de la tarjeta',
31
- }),
32
- new TextInput({
33
- id: 'cardHeight',
34
- label: 'Alto',
35
- required: false,
36
- description: 'Altura de la tarjeta',
37
- }),
38
- new TextInput({
8
+ new NumberInput({
9
+ id: 'topSeparationCard',
10
+ label: 'Separación desde arriba',
11
+ description: 'Separación de la tarjeta del margen superior',
12
+ }),
13
+ new NumberInput({
14
+ id: 'leftSeparationCard',
15
+ label: 'Separación desde izquierda',
16
+ description: 'Separación de la tarjeta del margen izquierdo',
17
+ }),
18
+ new NumberInput({ id: 'cardWidth', label: 'Ancho', required: false, description: 'Ancho de la tarjeta' }),
19
+ new NumberInput({ id: 'cardHeight', label: 'Alto', required: false, description: 'Altura de la tarjeta' }),
20
+ new NumberInput({
39
21
  id: 'cardGap',
40
22
  label: 'Separación entre elementos',
41
23
  required: false,
@@ -43,32 +25,16 @@ export const appeareanceInputs = [
43
25
  }),
44
26
 
45
27
  new Label({ label: 'Textos de la tarjeta' }),
46
- new TextFormat({
47
- id: 'aqiFormat',
48
- label: 'Formato del índice de calidad del aire',
49
- }),
50
- new TextFormat({
51
- id: 'stationFormat',
52
- label: 'Formato de estación que realizó la medición',
53
- }),
54
- new TextFormat({
55
- id: 'qualityFormat',
56
- label: 'Formato del mensaje sobre la calidad del aire',
57
- }),
28
+ new TextFormat({ id: 'aqiFormat', label: 'Formato del índice de calidad del aire' }),
29
+ new TextFormat({ id: 'stationFormat', label: 'Formato de estación que realizó la medición' }),
30
+ new TextFormat({ id: 'qualityFormat', label: 'Formato del mensaje sobre la calidad del aire' }),
58
31
 
59
32
  new Label({ label: 'Datos' }),
60
- new SelectInput({
61
- id: 'updateData',
62
- label: 'Frecuencia con la que se piden datos',
63
- items: [
64
- { label: '1 minuto', value: 1 },
65
- { label: '5 minutos', value: 5 },
66
- { label: '10 minutos', value: 10 },
67
- { label: '30 minutos', value: 30 },
68
- { label: '45 minutos', value: 45 },
69
- { label: '1 hora', value: 60 },
70
- ],
71
- defaultValue: 1,
33
+ new TextInput({
34
+ id: 'cityInput',
35
+ label: 'Ciudad a buscar',
36
+ description:
37
+ 'Ciudad de la que se quiere medir el aire. Para ver la ciudades disponibles se puede consultar aquí: https://aqicn.org/here',
72
38
  }),
73
39
  new TextInput({ id: 'msj0', label: 'Mensaje sin Datos' }),
74
40
  new TextFormat({ id: 'formatMjs', label: 'Formato Mensaje sin Datos' }),
@@ -1,8 +1,8 @@
1
- import { Group } from "@vixoniccom/modules";
2
- import { appeareanceInputs } from "./AppeareanceInputs";
1
+ import { Group } from '@vixoniccom/modules'
2
+ import { appeareanceInputs } from './AppeareanceInputs'
3
3
 
4
4
  export const appeareanceGroup = new Group({
5
5
  id: 'appeareanceGroup',
6
6
  label: 'Apariencia',
7
- items: [...appeareanceInputs]
8
- })
7
+ items: [...appeareanceInputs],
8
+ })
@@ -9,13 +9,6 @@
9
9
  "type": "label",
10
10
  "label": "General"
11
11
  },
12
- {
13
- "id": "padding",
14
- "label": "Márgenes",
15
- "type": "text-input",
16
- "description": "CSS para mover la tarjeta. El formato es arriba/derecha/abajo/izquieda",
17
- "required": false
18
- },
19
12
  {
20
13
  "id": "backgroundImage",
21
14
  "label": "Fondo",
@@ -31,24 +24,36 @@
31
24
  "type": "label",
32
25
  "label": "Diseño de la tarjeta"
33
26
  },
27
+ {
28
+ "id": "topSeparationCard",
29
+ "label": "Separación desde arriba",
30
+ "type": "number-input",
31
+ "description": "Separación de la tarjeta del margen superior"
32
+ },
33
+ {
34
+ "id": "leftSeparationCard",
35
+ "label": "Separación desde izquierda",
36
+ "type": "number-input",
37
+ "description": "Separación de la tarjeta del margen izquierdo"
38
+ },
34
39
  {
35
40
  "id": "cardWidth",
36
41
  "label": "Ancho",
37
- "type": "text-input",
42
+ "type": "number-input",
38
43
  "description": "Ancho de la tarjeta",
39
44
  "required": false
40
45
  },
41
46
  {
42
47
  "id": "cardHeight",
43
48
  "label": "Alto",
44
- "type": "text-input",
49
+ "type": "number-input",
45
50
  "description": "Altura de la tarjeta",
46
51
  "required": false
47
52
  },
48
53
  {
49
54
  "id": "cardGap",
50
55
  "label": "Separación entre elementos",
51
- "type": "text-input",
56
+ "type": "number-input",
52
57
  "description": "Separación entre los elementos de la tarjeta",
53
58
  "required": false
54
59
  },
@@ -76,36 +81,10 @@
76
81
  "label": "Datos"
77
82
  },
78
83
  {
79
- "id": "updateData",
80
- "label": "Frecuencia con la que se piden datos",
81
- "type": "select-input",
82
- "items": [
83
- {
84
- "label": "1 minuto",
85
- "value": 1
86
- },
87
- {
88
- "label": "5 minutos",
89
- "value": 5
90
- },
91
- {
92
- "label": "10 minutos",
93
- "value": 10
94
- },
95
- {
96
- "label": "30 minutos",
97
- "value": 30
98
- },
99
- {
100
- "label": "45 minutos",
101
- "value": 45
102
- },
103
- {
104
- "label": "1 hora",
105
- "value": 60
106
- }
107
- ],
108
- "defaultValue": 1
84
+ "id": "cityInput",
85
+ "label": "Ciudad a buscar",
86
+ "type": "text-input",
87
+ "description": "Ciudad de la que se quiere medir el aire. Para ver la ciudades disponibles se puede consultar aquí: https://aqicn.org/here"
109
88
  },
110
89
  {
111
90
  "id": "msj0",
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "author": {
9
9
  "name": "Daniel Alvayay"
10
10
  },
11
- "version": "0.0.1-dev.4",
11
+ "version": "0.0.1-dev.6",
12
12
  "scripts": {
13
13
  "prepublishOnly": "vixonic-module-packager --mode=build",
14
14
  "watch": "vixonic-module-packager --mode=watch",
@@ -28,8 +28,8 @@
28
28
  "devDependencies": {
29
29
  "@types/react": "^17.0.35",
30
30
  "@types/react-dom": "^17.0.11",
31
- "@vixoniccom/module-packager": "^2.10.0",
32
- "@vixoniccom/modules": "^2.19.0",
31
+ "@vixoniccom/module-packager": "^2.6.0",
32
+ "@vixoniccom/modules": "^2.16.0",
33
33
  "standard-version": "^9.3.1"
34
34
  }
35
35
  }
package/src/App.tsx CHANGED
@@ -1,11 +1,11 @@
1
1
  import axios from 'axios'
2
+ import localforage from 'localforage'
2
3
  import React, { useEffect, useState } from 'react'
3
4
  import { Card } from './components/Card'
4
5
  import { FontLoader } from './components/FontLoader'
5
6
  import { FormattedText } from './components/FormattedText'
6
- import { AirQuality, StorageData } from './types'
7
- import { API_RESPONSE_STATUS } from './utils'
8
- import localforage from 'localforage'
7
+ import { AirQuality, AqiData, StorageData } from './types'
8
+ import { API_RESPONSE_STATUS, TOKEN } from './utils'
9
9
 
10
10
  interface Props {
11
11
  data: VixonicData
@@ -15,8 +15,9 @@ interface Props {
15
15
  export const App: React.FunctionComponent<Props> = ({ data, start }) => {
16
16
  const { parameters, downloadsPath } = data
17
17
  const backgroundImageState = parameters.backgroundImage ? `url('${downloadsPath}/${parameters.backgroundImage.filename}')` : ''
18
- const [formattedData, setFormattedData] = useState<AirQuality | null>()
19
- const updateTime = (parameters?.updateData || 1) * 60000
18
+ const [formattedData, setFormattedData] = useState<AqiData>()
19
+ const cityInput = parameters?.cityInput || "santiago"
20
+ const updateTime = 600000
20
21
 
21
22
  const refetchData = (referenceDate: Date): boolean => {
22
23
  const now = new Date()
@@ -29,13 +30,11 @@ export const App: React.FunctionComponent<Props> = ({ data, start }) => {
29
30
  const differenceMinutes = Math.abs(now.getTime() - referenceDate.getTime())
30
31
  return differenceMinutes >= updateTime
31
32
  }
32
-
33
33
  return true
34
34
  }
35
35
 
36
36
  const requestData = async (): Promise<AirQuality | null> => {
37
- const TOKEN = "9fa7d8df1a621c9d518a351a13ff9b94093b9dac"
38
- const URL = `https://api.waqi.info/feed/here/?token=${TOKEN}`
37
+ const URL = `https://api.waqi.info/feed/${cityInput}/?token=${TOKEN}`
39
38
  try {
40
39
  const response = await axios.get<AirQuality>(URL)
41
40
  if (response?.status === 200) {
@@ -43,21 +42,34 @@ export const App: React.FunctionComponent<Props> = ({ data, start }) => {
43
42
  }
44
43
  return null
45
44
  } catch (error) {
46
- console.log(error)
47
45
  return null
48
46
  }
49
47
  }
50
48
 
49
+ const processData = (response: AirQuality | null): AqiData => {
50
+ let data: AqiData = { city: cityInput, station: "Estación desconocida" }
51
+ if (response && response.status === API_RESPONSE_STATUS.OK) {
52
+ data = {
53
+ aqi: response.data.aqi,
54
+ city: cityInput,
55
+ station: response.data.city.name
56
+ }
57
+ }
58
+ return data
59
+ }
60
+
51
61
  const getData = async () => {
52
62
  const storageData: StorageData | null = await localforage.getItem('aqi')
53
63
  let data
54
- if (!storageData?.item || refetchData(storageData?.date ?? new Date(0))) {
64
+ if (!storageData?.item || storageData?.item.city !== parameters.cityInput || !storageData?.date || refetchData(new Date(storageData.date))) {
55
65
  data = await requestData()
56
- await localforage.setItem('aqi', { item: data, date: new Date() })
66
+ const processedData = processData(data)
67
+ await localforage.setItem('aqi', { item: processedData, date: new Date() })
68
+ setFormattedData(processedData)
57
69
  } else {
58
70
  data = storageData.item
71
+ setFormattedData(data)
59
72
  }
60
- setFormattedData(data)
61
73
  }
62
74
 
63
75
  useEffect(() => {
@@ -67,48 +79,60 @@ export const App: React.FunctionComponent<Props> = ({ data, start }) => {
67
79
  getData()
68
80
  }, updateTime)
69
81
  return () => clearInterval(interval)
70
- }, [start, updateTime])
82
+ }, [start, updateTime, parameters.cityInput])
71
83
 
72
84
  return (
73
- <div
74
- style={{
75
- position: 'absolute',
76
- top: 0,
77
- bottom: 0,
78
- left: 0,
79
- right: 0,
80
- backgroundImage: backgroundImageState,
81
- backgroundSize: '100% 100%',
82
- padding: parameters?.padding
83
- }}
84
- >
85
- {formattedData?.status === API_RESPONSE_STATUS.OK ? (
86
- <div>
87
- <FontLoader paths={['aqiFormat.font', 'stationFormat.font', 'qualityFormat.font']} parameters={parameters} downloadsPath={downloadsPath} />
85
+ <div style={{
86
+ position: 'absolute',
87
+ top: 0,
88
+ bottom: 0,
89
+ left: 0,
90
+ right: 0,
91
+ display: "flex",
92
+ backgroundImage: backgroundImageState,
93
+ backgroundSize: '100% 100%',
94
+ }}>
95
+ <div style={{
96
+ width: "100%",
97
+ height: "100%",
98
+ position: "relative"
99
+ }}>
100
+ {formattedData ? (
101
+ <div style={{
102
+ position: "absolute",
103
+ top: `${parameters.topSeparationCard || 0}px`,
104
+ left: `${parameters.leftSeparationCard || 0}px`
105
+ }}>
106
+ <FontLoader paths={['aqiFormat.font', 'stationFormat.font', 'qualityFormat.font']} parameters={parameters} downloadsPath={downloadsPath} />
88
107
 
89
- <Card data={formattedData?.data}
90
- format={{
91
- cardWidth: parameters?.cardWidth,
92
- cardHeight: parameters?.cardHeight,
93
- cardGap: parameters?.cardGap,
94
- aqiFormat: parameters?.aqiFormat,
95
- stationFormat: parameters?.stationFormat,
96
- qualityFormat: parameters?.qualityFormat
97
- }} />
98
- </div>
99
- ) : (
100
- <div>
101
- <FontLoader paths={['formatMjs.font']} parameters={parameters} downloadsPath={downloadsPath} />
108
+ <Card data={formattedData}
109
+ format={{
110
+ cardWidth: parameters?.cardWidth,
111
+ cardHeight: parameters?.cardHeight,
112
+ cardGap: parameters?.cardGap,
113
+ aqiFormat: parameters?.aqiFormat,
114
+ stationFormat: parameters?.stationFormat,
115
+ qualityFormat: parameters?.qualityFormat
116
+ }} />
117
+ </div>
118
+ ) : (
102
119
  <div style={{
103
- display: 'flex',
104
- position: 'relative',
105
- flex: '1 1 0%',
106
- flexDirection: 'column',
120
+ position: "absolute",
121
+ top: `${parameters.topSeparationCard || 0}px`,
122
+ left: `${parameters.leftSeparationCard || 0}px`
107
123
  }}>
108
- <FormattedText text={parameters?.msj0 || 'No hay datos para mostrar'} format={parameters?.formatMjs} />
124
+ <FontLoader paths={['formatMjs.font']} parameters={parameters} downloadsPath={downloadsPath} />
125
+ <div style={{
126
+ display: 'flex',
127
+ position: 'relative',
128
+ flex: '1 1 0%',
129
+ flexDirection: 'column',
130
+ }}>
131
+ <FormattedText text={parameters?.msj0 || 'No hay datos para mostrar'} format={parameters?.formatMjs} />
132
+ </div>
109
133
  </div>
110
- </div>
111
- )}
134
+ )}
135
+ </div>
112
136
  </div>
113
137
  )
114
138
  }
@@ -1,15 +1,15 @@
1
- import React from 'react'
2
- import { assingAirQuality } from '../utils'
3
- import { Data } from '../types';
4
- import { TextFormat } from '@vixoniccom/modules'
5
- import { FormattedText } from './FormattedText'
1
+ import React from 'react';
2
+ import { assingAirQuality } from '../utils';
3
+ import { AqiData } from '../types';
4
+ import { TextFormat } from '@vixoniccom/modules';
5
+ import { FormattedText } from './FormattedText';
6
6
 
7
7
  interface Props {
8
- data: Data;
8
+ data: AqiData;
9
9
  format: {
10
- cardWidth?: string;
11
- cardHeight?: string;
12
- cardGap?: string;
10
+ cardWidth?: number;
11
+ cardHeight?: number;
12
+ cardGap?: number;
13
13
  aqiFormat?: TextFormat.Value;
14
14
  stationFormat?: TextFormat.Value;
15
15
  qualityFormat?: TextFormat.Value;
@@ -17,34 +17,36 @@ interface Props {
17
17
  }
18
18
 
19
19
  export const Card: React.FunctionComponent<Props> = ({ data, format }) => {
20
- const { color, quality } = assingAirQuality(data?.aqi)
20
+ const { color, quality } = assingAirQuality(data?.aqi || -1)
21
+ const city = data.station === "Estación desconocida" ? data.station : data.city
22
+
21
23
  return (
22
24
  <div style={{
23
25
  display: 'flex',
24
- width: format.cardWidth || 300,
25
- height: format.cardHeight || 200,
26
+ width: `${format.cardWidth || 300}px`,
27
+ height: `${format.cardHeight || 200}px`,
26
28
  flexDirection: 'column',
27
- padding: '1rem',
28
29
  backgroundColor: color,
29
- border: '2px solid #000',
30
- // gap: format.cardGap || "2rem",
30
+ borderRadius: "10px"
31
31
  }}>
32
- <div style={{
33
- textAlign: `${format.aqiFormat?.alignment?.horizontal || 'left'}`,
34
- padding: `${format.cardGap || "2rem"}`
35
- }}>
36
- <FormattedText text={String(data?.aqi)} format={format.aqiFormat} />
37
- </div>
32
+ {(data?.aqi) && (
33
+ <div style={{
34
+ textAlign: `${format.aqiFormat?.alignment?.horizontal || 'left'}`,
35
+ padding: `${format.cardGap || 2}rem`
36
+ }}>
37
+ <FormattedText text={String(data?.aqi)} format={format.aqiFormat} />
38
+ </div>
39
+ )}
38
40
  <div style={{
39
41
  textAlign: `${format.stationFormat?.alignment?.horizontal || 'left'}`,
40
- padding: `${format.cardGap || "2rem"}`,
42
+ padding: `${format.cardGap || 2}rem`,
41
43
  }}>
42
- <FormattedText text={String(`Estación: ${data?.city?.name}`)} format={format.stationFormat} />
44
+ <FormattedText text={city} format={format.stationFormat} />
43
45
  </div>
44
46
  <div style={{
45
47
  textAlign: `${format.qualityFormat?.alignment?.horizontal || 'left'}`,
46
- padding: `${format.cardGap || "2rem"}`,
47
- marginTop: "1rem"
48
+ padding: `${format.cardGap || 2}rem`,
49
+ marginTop: '1rem'
48
50
  }}>
49
51
  <FormattedText text={data?.aqi ? quality : ''} format={format.qualityFormat} />
50
52
  </div>
@@ -26,8 +26,8 @@ export const FontLoader: React.FunctionComponent<Props> = ({ paths, parameters,
26
26
  }
27
27
  return `
28
28
  @font-face {
29
- font-family: "${font.family}";
30
- src: url("${font.src}");
29
+ font-family: '${font.family}';
30
+ src: url('${font.src}');
31
31
  }
32
32
  `
33
33
  } catch (err) {
@@ -61,7 +61,7 @@ export const FormattedText: React.FunctionComponent<Props> = ({ text, format, ma
61
61
  <div style={containerStyle}>
62
62
  <span style={{
63
63
  color: format?.fontColor,
64
- fontFamily: checkNested(format, 'font.filename') ? `"${format?.font?.filename?.replace('.', '-')}"` : '',
64
+ fontFamily: checkNested(format, 'font.filename') ? `'${format?.font?.filename?.replace('.', '-')}'` : '',
65
65
  fontSize: `${format?.fontSize}${unit}`,
66
66
  textAlign: checkNested(format, 'alignment.horizontal') ? format?.alignment?.horizontal : 'left',
67
67
  lineHeight: lineHeight,
package/src/index.html CHANGED
@@ -1,11 +1,11 @@
1
1
  <!DOCTYPE html>
2
- <html style="position: absolute; height:100%; width: 100%; overflow: hidden;">
2
+ <html style='position: absolute; height:100%; width: 100%; overflow: hidden;'>
3
3
  <head>
4
4
  <title></title>
5
- <meta charset="utf-8">
5
+ <meta charset='utf-8'>
6
6
  </head>
7
- <body style="margin:0; overflow: hidden;">
8
- <div id="root" style="position: absolute; top: 0; right: 0; bottom: 0; left: 0; overflow: hidden;">
7
+ <body style='margin:0; overflow: hidden;'>
8
+ <div id='root' style='position: absolute; top: 0; right: 0; bottom: 0; left: 0; overflow: hidden;'>
9
9
  </div>
10
10
  </body>
11
11
  </html>
@@ -1,9 +1,40 @@
1
1
  declare type VixonicData = {
2
2
  downloadsPath: string
3
- services: { [key: string]: { data?: any, updatedAt?: number } }
3
+ services: { [key: string]: { data?: any; updatedAt?: number } }
4
4
  parameters: VixonicParameters
5
5
  }
6
6
 
7
7
  declare type VixonicParameters = Partial<{
8
- padding: string, backgroundImage: {id?: string, filename?: string, extension?: string}, cardWidth: string, cardHeight: string, cardGap: string, aqiFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, stationFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, qualityFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, updateData: 1 | 5 | 10 | 30 | 45 | 60, msj0: string, formatMjs: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }
9
- }>
8
+ backgroundImage: { id?: string; filename?: string; extension?: string }
9
+ topSeparationCard: number
10
+ leftSeparationCard: number
11
+ cardWidth: number
12
+ cardHeight: number
13
+ cardGap: number
14
+ aqiFormat: {
15
+ fontSize?: number
16
+ fontColor?: string
17
+ alignment?: { horizontal?: 'left' | 'right' | 'center' }
18
+ font?: { filename: string; id: string; __isAsset: true }
19
+ }
20
+ stationFormat: {
21
+ fontSize?: number
22
+ fontColor?: string
23
+ alignment?: { horizontal?: 'left' | 'right' | 'center' }
24
+ font?: { filename: string; id: string; __isAsset: true }
25
+ }
26
+ qualityFormat: {
27
+ fontSize?: number
28
+ fontColor?: string
29
+ alignment?: { horizontal?: 'left' | 'right' | 'center' }
30
+ font?: { filename: string; id: string; __isAsset: true }
31
+ }
32
+ cityInput: string
33
+ msj0: string
34
+ formatMjs: {
35
+ fontSize?: number
36
+ fontColor?: string
37
+ alignment?: { horizontal?: 'left' | 'right' | 'center' }
38
+ font?: { filename: string; id: string; __isAsset: true }
39
+ }
40
+ }>
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "parameters": {
3
- "padding": "200px 100px 100px 600px",
4
3
  "backgroundImage": {
5
4
  "id": "earthquakes",
6
5
  "filename": "Earthquakes.png",
7
6
  "__isAsset": true
8
7
  },
9
- "cardWidth": "700px",
10
- "cardHeight": "600px",
11
- "cardGap": "2rem",
8
+ "cityInput": "Santiago",
9
+ "topSeparationCard": 200,
10
+ "leftSeparationCard": 600,
11
+ "cardWidth": 700,
12
+ "cardHeight": 600,
13
+ "cardGap": 2,
12
14
  "aqiFormat": {
13
15
  "fontSize": 18,
14
16
  "fontColor": "#000000",
@@ -31,4 +33,4 @@
31
33
  }
32
34
  }
33
35
  }
34
- }
36
+ }
package/src/types.d.ts CHANGED
@@ -1,14 +1,23 @@
1
+ export interface StorageData {
2
+ item: AqiData
3
+ date: Date
4
+ }
5
+
6
+ export interface AqiData {
7
+ city: string
8
+ aqi?: number
9
+ station: string
10
+ }
11
+
1
12
  export interface AirQuality {
2
- status: 'ok' | 'error' | number
13
+ status: Status
3
14
  data: Data
4
15
  }
5
16
 
6
- export interface StorageData {
7
- item: AirQuality
8
- date: Date
9
- }
17
+ type Status = 'ok' | 'error'
10
18
 
11
19
  export interface Data {
20
+ status?: Status
12
21
  aqi: number
13
22
  idx: number
14
23
  attributions: Attribution[]