Skip to content
37 changes: 18 additions & 19 deletions app/client/components/DashboardForceCurve.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,20 @@ import { Chart, Filler, Legend, LinearScale, LineController, LineElement, PointE
@customElement('dashboard-force-curve')
export class DashboardForceCurve extends AppElement {
static styles = css`
:host {
display: flex;
flex-direction: column;
}

.title {
font-size: 80%;
text-align: center;
padding: 0.2em 0;
}

canvas {
margin-top: 24px;
flex: 1;
min-height: 0;
}
`

Expand All @@ -31,6 +43,7 @@ export class DashboardForceCurve extends AppElement {

firstUpdated () {
const ctx = this.renderRoot.querySelector('#chart').getContext('2d')
const baseFontSize = parseFloat(getComputedStyle(this).fontSize)
this._chart = new Chart(
ctx,
{
Expand Down Expand Up @@ -58,27 +71,12 @@ export class DashboardForceCurve extends AppElement {
...ctx.dataset.data.map((point) => point.y)
) === ctx.dataset.data[ctx.dataIndex].y,
font: {
size: 16
size: baseFontSize * 0.4
},
color: 'rgb(255,255,255)'
},
legend: {
title: {
display: true,
text: 'Force Curve',
color: 'rgb(255,255,255)',
font: {
size: 32
},
padding: {
}
},
labels: {
boxWidth: 0,
font: {
size: 0
}
}
display: false,
}
},
scales: {
Expand Down Expand Up @@ -119,7 +117,8 @@ export class DashboardForceCurve extends AppElement {
}

return html`
<canvas id="chart"></canvas>
<div class="title">Force Curve</div>
<canvas id="chart"></canvas>
`
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,83 @@
/*
Open Rowing Monitor, https://github.com/JaapvanEkris/openrowingmonitor

Component that renders the action buttons of the dashboard
Toolbar component combining settings and action buttons
*/

import { AppElement, html, css } from './AppElement.js'
import { customElement, property, state } from 'lit/decorators.js'
import { iconUndo, iconExpand, iconCompress, iconPoweroff, iconBluetooth, iconUpload, iconHeartbeat, iconAntplus } from '../lib/icons.js'
import { iconSettings, iconUndo, iconExpand, iconCompress, iconPoweroff, iconBluetooth, iconUpload, iconHeartbeat, iconAntplus } from '../lib/icons.js'
import './SettingsDialog.js'
import './AppDialog.js'

@customElement('dashboard-actions')
export class DashboardActions extends AppElement {
@customElement('dashboard-toolbar')
export class DashboardToolbar extends AppElement {
static styles = css`
:host {
display: flex;
justify-content: space-between;
align-items: center;
gap: 0.5em;
padding: 0.2em 0.3em;
background: var(--theme-widget-color);
border-radius: var(--theme-border-radius);
}

.button-group {
display: flex;
align-items: center;
gap: 0.3em;
flex-wrap: wrap;
}

button {
position: relative;
outline:none;
background-color: var(--theme-button-color);
display: flex;
justify-content: center;
align-items: center;
width: 2.5em;
height: 2.5em;
padding: 0;
border: 0;
border-radius: var(--theme-border-radius);
background: var(--theme-button-color);
color: var(--theme-font-color);
margin: 0.2em 4px;
font-size: 60%;
text-decoration: none;
display: inline-flex;
width: 3.2em;
min-width: 3.2em;
height: 2.2em;
justify-content: center;
align-items: center;
font-size: 0.4em;
cursor: pointer;
}

button:hover {
filter: brightness(150%);
}

button > div.text {
button .text {
position: absolute;
left: 2px;
bottom: 2px;
font-size: 40%;
}

#fullscreen-icon {
display: inline-flex;
.icon {
height: 1.2em;
}

.top-button-group {
.peripheral-mode-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}

#windowed-icon {
display: none;
}

.icon {
height: 1.7em;
flex-direction: row;
align-items: center;
gap: 0.1em;
}

.peripheral-mode {
font-size: 50%;
font-size: 0.3em;
}

.fullscreen-icon { display: flex; }
.windowed-icon { display: none; }

@media (display-mode: fullscreen) {
#fullscreen-icon {
display: none;
}
#windowed-icon {
display: inline-flex;
}
.fullscreen-icon { display: none; }
.windowed-icon { display: flex; }
}
`

Expand All @@ -85,24 +93,35 @@ export class DashboardActions extends AppElement {

render () {
return html`
<div class="top-button-group">
<button @click=${this.reset}>${iconUndo}</button>
${this.renderOptionalButtons()}
<button @click=${this.switchHrmPeripheralMode}>
${iconHeartbeat}
<div class="text">${this.config?.hrmPeripheralMode}</div>
</button>
<button @click=${this.switchAntPeripheralMode}>
${iconAntplus}
<div class="text">${this.config?.antPeripheralMode}</div>
</button>
</div>
<div class="text-button">
<button @click=${this.switchBlePeripheralMode}>${iconBluetooth}</button>
<div class="peripheral-mode">${this.blePeripheralMode()}</div>
</div>
${this._dialog ? this._dialog : ''}
`
<div class="button-group">
<button @click=${this.openSettings} title="Settings">
${iconSettings}
</button>
<button @click=${this.reset} title="Reset">
${iconUndo}
</button>
${this.renderOptionalButtons()}
</div>

<div class="button-group">
<button @click=${this.switchHrmPeripheralMode} title="Heart Rate Monitor">
${iconHeartbeat}
<div class="text">${this.config?.hrmPeripheralMode}</div>
</button>
<button @click=${this.switchAntPeripheralMode} title="ANT+ Mode">
${iconAntplus}
<div class="text">${this.config?.antPeripheralMode}</div>
</button>
<div class="peripheral-mode-container">
<button @click=${this.switchBlePeripheralMode} title="Bluetooth Mode">
${iconBluetooth}
</button>
<div class="peripheral-mode">${this.blePeripheralMode()}</div>
</div>
</div>

${this._dialog ? this._dialog : ''}
`
}

firstUpdated () {
Expand All @@ -120,30 +139,23 @@ export class DashboardActions extends AppElement {

renderOptionalButtons () {
const buttons = []
// changing to fullscreen mode only makes sence when the app is openend in a regular
// webbrowser (kiosk and standalone mode are always in fullscreen view) and if the
// browser supports this feature
if (this._appMode === 'BROWSER' && document.documentElement.requestFullscreen) {
buttons.push(html`
<button @click=${this.toggleFullscreen}>
<div id="fullscreen-icon">${iconExpand}</div>
<div id="windowed-icon">${iconCompress}</div>
</button>
`)
<button @click=${this.toggleFullscreen} title="Toggle Fullscreen">
<span class="fullscreen-icon">${iconExpand}</span>
<span class="windowed-icon">${iconCompress}</span>
</button>
`)
}
// add a button to power down the device, if browser is running on the device in kiosk mode
// and the shutdown feature is enabled
// (might also make sence to enable this for all clients but then we would need visual feedback)
if (this._appMode === 'KIOSK' && this.config?.shutdownEnabled) {
buttons.push(html`
<button @click=${this.shutdown}>${iconPoweroff}</button>
`)
<button @click=${this.shutdown} title="Shutdown">${iconPoweroff}</button>
`)
}

if (this.config?.uploadEnabled) {
buttons.push(html`
<button @click=${this.uploadTraining}>${iconUpload}</button>
`)
<button @click=${this.uploadTraining} title="Upload Training">${iconUpload}</button>
`)
}
return buttons
}
Expand All @@ -166,6 +178,12 @@ export class DashboardActions extends AppElement {
}
}

openSettings () {
this._dialog = html`<settings-dialog .config=${this.config.guiConfigs} @close=${() => {
this._dialog = undefined
}}></settings-dialog>`
}

toggleFullscreen () {
const fullscreenElement = document.getElementsByTagName('web-app')[0]
if (!document.fullscreenElement) {
Expand Down Expand Up @@ -195,31 +213,29 @@ export class DashboardActions extends AppElement {

uploadTraining () {
this._dialog = html`
<app-dialog @close=${dialogClosed}>
<app-dialog @close=${(event) => {
this._dialog = undefined
if (event.detail === 'confirm') {
this.sendEvent('triggerAction', { command: 'upload' })
}
}}>
<legend>${iconUpload}<br/>Upload training?</legend>
<p>Do you want to finish your workout and upload it to webservices (Strava, Intervals.icu and RowsAndAll)?</p>
</app-dialog>
`
function dialogClosed (event) {
this._dialog = undefined
if (event.detail === 'confirm') {
this.sendEvent('triggerAction', { command: 'upload' })
}
}
}

shutdown () {
this._dialog = html`
<app-dialog @close=${dialogClosed}>
<app-dialog @close=${(event) => {
this._dialog = undefined
if (event.detail === 'confirm') {
this.sendEvent('triggerAction', { command: 'shutdown' })
}
}}>
<legend>${iconPoweroff}<br/>Shutdown Open Rowing Monitor?</legend>
<p>Do you want to shutdown the device?</p>
</app-dialog>
`
function dialogClosed (event) {
this._dialog = undefined
if (event.detail === 'confirm') {
this.sendEvent('triggerAction', { command: 'shutdown' })
}
}
}
}
Loading