adds a first test for a working global frontend state

This commit is contained in:
Lars Berning 2022-01-09 22:00:58 +01:00
parent 4737669216
commit 2eed3fa6dd
No known key found for this signature in database
GPG Key ID: 028E73C9E1D8A0B3
5 changed files with 63 additions and 9 deletions

View File

@ -6,8 +6,9 @@
*/ */
import { AppElement, html, css } from './AppElement' import { AppElement, html, css } from './AppElement'
import { customElement } from 'lit/decorators.js' import { APP_STATE } from '../store/appState'
import { createApp } from '../lib/network.js' import { customElement, state } from 'lit/decorators.js'
import { createApp } from '../lib/network'
import './PerformanceDashboard' import './PerformanceDashboard'
@customElement('web-app') @customElement('web-app')
@ -17,11 +18,22 @@ export class App extends AppElement {
` `
} }
@state()
globalAppState = APP_STATE
constructor () { constructor () {
super() super()
this.app = createApp() this.app = createApp(this.globalAppState)
window.app = this.app window.app = this.app
this.app.setMetricsCallback(metrics => this.metricsUpdated(metrics)) this.app.setMetricsCallback(metrics => this.metricsUpdated(metrics))
// this is how we implement changes to the global state:
// once any child component sends this CustomEvent we update the global state according
// to the changes that were passed to us
this.addEventListener('app-state-changed', (event) => {
const newState = event.detail
this.globalAppState = newState
})
} }
static properties = { static properties = {
@ -30,7 +42,10 @@ export class App extends AppElement {
render () { render () {
return html` return html`
<performance-dashboard .metrics=${this.metrics}></performance-dashboard> <performance-dashboard
.appState=${this.globalAppState}
.metrics=${this.metrics}
></performance-dashboard>
` `
} }

View File

@ -6,10 +6,30 @@
*/ */
import { LitElement } from 'lit' import { LitElement } from 'lit'
import { property } from 'lit/decorators.js'
import { APP_STATE } from '../store/appState'
export * from 'lit' export * from 'lit'
export class AppElement extends LitElement { export class AppElement extends LitElement {
// todo: should use shadow root once the global style file is dissolved into the components // this is how we implement a global state: a global state object is passed via properties
// to child components
@property({ type: Object })
appState = APP_STATE
// ..and state changes are send back to the root component of the app by dispatching
// a CustomEvent
updateState () {
this.dispatchEvent(
new CustomEvent('app-state-changed', {
detail: { ...this.appState },
bubbles: true,
composed: true
})
)
}
// currently we do not use shadow root since there is still a global style file
// but maybe one day we dissolve it into the components and use shadow dom instead
createRenderRoot () { createRenderRoot () {
return this return this
} }

View File

@ -28,10 +28,11 @@ export class DashboardActions extends AppElement {
<div id="windowed-icon">${icon_compress}</div> <div id="windowed-icon">${icon_compress}</div>
</button> </button>
<button @click=${this.close} id="close-button">${icon_poweroff}</button> <button @click=${this.close} id="close-button">${icon_poweroff}</button>
<button @lick=${this.switchPeripheralMode}>${icon_bluetooth}</button> <button @click=${this.switchPeripheralMode}>${icon_bluetooth}</button>
<div class="metric-unit">${this.peripheralMode}</div> <div class="metric-unit">${this.appState.peripheralMode}</div>
` `
} }
// <div class="metric-unit">${this.peripheralMode}</div>
toggleFullscreen () { toggleFullscreen () {
const fullscreenElement = document.getElementsByTagName('web-app')[0] const fullscreenElement = document.getElementsByTagName('web-app')[0]
@ -54,6 +55,9 @@ export class DashboardActions extends AppElement {
} }
switchPeripheralMode () { switchPeripheralMode () {
window.app.switchPeripheralMode() // window.app.switchPeripheralMode()
// todo: this is just a test property to see if the concept works...
this.appState.peripheralMode = 'PM5'
this.updateState()
} }
} }

View File

@ -6,6 +6,7 @@
*/ */
import { AppElement, html, css } from './AppElement' import { AppElement, html, css } from './AppElement'
import { APP_STATE } from '../store/appState'
import { customElement, property } from 'lit/decorators.js' import { customElement, property } from 'lit/decorators.js'
import './DashboardMetric' import './DashboardMetric'
import './DashboardActions' import './DashboardActions'
@ -21,6 +22,9 @@ export class PerformanceDashboard extends AppElement {
@property({ type: Object }) @property({ type: Object })
metrics metrics
@property({ type: Object })
appState = APP_STATE
render () { render () {
return html` return html`
<dashboard-metric .icon=${icon_route} .unit=${this.metrics?.distanceTotal?.unit} .value=${this.metrics?.distanceTotal?.value}></dashboard-metric> <dashboard-metric .icon=${icon_route} .unit=${this.metrics?.distanceTotal?.unit} .value=${this.metrics?.distanceTotal?.value}></dashboard-metric>
@ -34,7 +38,7 @@ export class PerformanceDashboard extends AppElement {
: html`<dashboard-metric .icon=${icon_paddle} unit="total" .value=${this.metrics?.strokesTotal?.value}></dashboard-metric>`} : html`<dashboard-metric .icon=${icon_paddle} unit="total" .value=${this.metrics?.strokesTotal?.value}></dashboard-metric>`}
<dashboard-metric .icon=${icon_fire} unit="kcal" .value=${this.metrics?.caloriesTotal?.value}></dashboard-metric> <dashboard-metric .icon=${icon_fire} unit="kcal" .value=${this.metrics?.caloriesTotal?.value}></dashboard-metric>
<dashboard-metric .icon=${icon_clock} .value=${this.metrics?.durationTotalFormatted?.value}></dashboard-metric> <dashboard-metric .icon=${icon_clock} .value=${this.metrics?.durationTotalFormatted?.value}></dashboard-metric>
<dashboard-actions .peripheralMode=${this.metrics?.peripheralMode?.value}></dashboard-actions> <dashboard-actions .appState=${this.appState} .peripheralMode=${this.metrics?.peripheralMode?.value}></dashboard-actions>
` `
} }
} }

View File

@ -0,0 +1,11 @@
'use strict'
/*
Open Rowing Monitor, https://github.com/laberning/openrowingmonitor
Defines the global state of the app
*/
export const APP_STATE = {
// todo: this is just a test property to see if the concept works...
peripheralMode: 'FTMSROWER'
}