diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml new file mode 100644 index 000000000..1eb009153 --- /dev/null +++ b/.github/workflows/nodejs.yml @@ -0,0 +1,34 @@ +name: Node CI + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16.x] + + steps: + - name: Checkout repository and submodules + uses: actions/checkout@v2 + with: + submodules: recursive + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - name: install testing dependencies + run: npm i + - name: test all apps and widgets + run: npm run test + - name: install typescript dependencies + working-directory: ./typescript + run: npm ci + - name: build types + working-directory: ./typescript + run: npm run build:types + - name: build all TS apps and widgets + working-directory: ./typescript + run: npm run build \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f3d0d2159..000000000 --- a/.travis.yml +++ /dev/null @@ -1,3 +0,0 @@ -language: node_js -node_js: - - "node" diff --git a/apps/banglerun/.gitignore b/apps/banglerun/.gitignore deleted file mode 100644 index c2658d7d1..000000000 --- a/apps/banglerun/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules/ diff --git a/apps/banglerun/ChangeLog b/apps/banglerun/ChangeLog deleted file mode 100644 index c778588cc..000000000 --- a/apps/banglerun/ChangeLog +++ /dev/null @@ -1,13 +0,0 @@ -0.01: First release -0.02: Bugfix time: Reset minutes to 0 when hitting 60 -0.03: Fix distance >=10 km (fix #529) -0.04: Use offscreen buffer for flickerless updates -0.05: Complete rewrite. New UI, GPS & HRM Kalman filters, activity logging -0.06: Reading HDOP directly from the GPS event (needs Espruino 2v07 or above) -0.07: Fixed GPS update, added guards against NaN values -0.08: Fix issue with GPS coordinates being wrong after the first one -0.09: Another GPS fix (log raw coordinates - not filtered ones) -0.10: Removed kalman filtering to allow distance log to work - Only log data every 5 seconds (not 1 sec) - Don't create a file until the first log entry is ready - Add labels for buttons diff --git a/apps/banglerun/README.md b/apps/banglerun/README.md deleted file mode 100644 index 80e984bfa..000000000 --- a/apps/banglerun/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# BangleRun - -An app for running sessions. Displays info and logs your run for later viewing. - -## Compilation - -The app is written in Typescript, and needs to be transpiled in order to be -run on the BangleJS. The easiest way to perform this step is by using the -ubiquitous [NPM package manager](https://www.npmjs.com/get-npm). - -After having installed NPM for your platform, checkout the `BangleApps` repo, -open a terminal, and navigate into the `apps/banglerun` folder. Then issue: - -``` -npm i -``` - -to install the project's build tools, and: - -``` -npm run build -``` - -To build the app. The last command will generate the `app.js` file, containing -the transpiled code for the BangleJS. diff --git a/apps/banglerun/app-icon.js b/apps/banglerun/app-icon.js deleted file mode 100644 index 9eeaced6e..000000000 --- a/apps/banglerun/app-icon.js +++ /dev/null @@ -1 +0,0 @@ -require("heatshrink").decompress(atob("mEwwIHEuAEDgP8ApMDAqAXBjAGD/E8AgUcgF8CAX/BgIFBn//wAFCv//8PwAoP///5Aon/8AcB+IFB4AFB8P/34FBgfj/8fwAFB4f+g4cBg/H/w/Cg+HKQcPx4FEh4/CAoMfAocOj4/CKYRwELIIFDLII6BAoZSBLIYeCgP+v4FD/k/GAQFBHgcD/ABBIIX4gIFBSYPwAoUPAog/B8AFEwAFDDQQCBQoQFCZYYFigCKEgFwgAA==")) diff --git a/apps/banglerun/app.js b/apps/banglerun/app.js deleted file mode 100644 index b79255171..000000000 --- a/apps/banglerun/app.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var t;!function(t){t.Stopped="STOP",t.Paused="PAUSE",t.Running="RUN"}(t||(t={}));const n={STOP:63488,PAUSE:65504,RUN:2016};function e(t,n,e){g.setColor(0),g.fillRect(n-60,e,n+60,e+30),g.setColor(65535),g.drawString(t,n,e)}function i(i){var s;g.setFontVector(30),g.setFontAlign(0,-1,0),e((i.distance/1e3).toFixed(2),60,55),e(function(t){const n=Math.round(t),e=Math.floor(n/3600),i=Math.floor(n/60)%60,s=n%60;return(e?e+":":"")+("0"+i).substr(-2)+":"+("0"+s).substr(-2)}(i.duration),172,55),e(function(t){if(t<.1667)return"__'__\"";const n=Math.round(1e3/t),e=Math.floor(n/60),i=n%60;return("0"+e).substr(-2)+"'"+("0"+i).substr(-2)+'"'}(i.speed),60,115),e(i.hr.toFixed(0),172,115),e(i.steps.toFixed(0),60,175),e(i.cadence.toFixed(0),172,175),g.setFont("6x8",2),g.setColor(i.gpsValid?2016:63488),g.fillRect(0,216,80,240),g.setColor(0),g.drawString("GPS",40,220),g.setColor(65535),g.fillRect(80,216,160,240),g.setColor(0),g.drawString(("0"+(s=new Date).getHours()).substr(-2)+":"+("0"+s.getMinutes()).substr(-2),120,220),g.setColor(n[i.status]),g.fillRect(160,216,230,240),g.setColor(0),g.drawString(i.status,200,220),g.setFont("6x8").setFontAlign(0,0,1).setColor(-1),i.status===t.Paused?g.drawString("START",236,60,1).drawString(" CLEAR ",236,180,1):i.status===t.Running?g.drawString(" PAUSE ",236,60,1).drawString(" PAUSE ",236,180,1):g.drawString("START",236,60,1).drawString(" ",236,180,1)}function s(t){g.clear(),g.setColor(50712),g.setFont("6x8",2),g.setFontAlign(0,-1,0),g.drawString("DIST (KM)",60,32),g.drawString("TIME",180,32),g.drawString("PACE",60,92),g.drawString("HEART",180,92),g.drawString("STEPS",60,152),g.drawString("CADENCE",180,152),i(t),Bangle.drawWidgets()}function a(n){n.status===t.Stopped&&function(t){const n=(new Date).toISOString().replace(/[-:]/g,""),e=`banglerun_${n.substr(2,6)}_${n.substr(9,6)}`;t.file=require("Storage").open(e,"w"),t.fileWritten=!1}(n),n.status===t.Running?n.status=t.Paused:n.status=t.Running,i(n)}const r={fix:NaN,lat:NaN,lon:NaN,alt:NaN,vel:NaN,dop:NaN,gpsValid:!1,x:NaN,y:NaN,z:NaN,t:NaN,timeSinceLog:0,hr:60,hrError:100,file:null,fileWritten:!1,drawing:!1,status:t.Stopped,duration:0,distance:0,speed:0,steps:0,cadence:0};var o;o=r,Bangle.on("GPS",n=>function(n,e){n.lat=e.lat,n.lon=e.lon,n.alt=e.alt,n.vel=e.speed/3.6,n.fix=e.fix,n.dop=e.hdop,n.gpsValid=n.fix>0,function(n){const e=Date.now();let i=(e-n.t)/1e3;if(isFinite(i)||(i=0),n.t=e,n.timeSinceLog+=i,n.status===t.Running&&(n.duration+=i),!n.gpsValid)return;const s=6371008.8+n.alt,a=n.lat*Math.PI/180,r=n.lon*Math.PI/180,o=s*Math.cos(a)*Math.cos(r),g=s*Math.cos(a)*Math.sin(r),d=s*Math.sin(a);if(!n.x)return n.x=o,n.y=g,void(n.z=d);const u=o-n.x,l=g-n.y,c=d-n.z,f=Math.sqrt(u*u+l*l+c*c);n.x=o,n.y=g,n.z=d,n.status===t.Running&&(n.distance+=f,n.speed=n.distance/n.duration||0,n.cadence=60*n.steps/n.duration||0)}(n),i(n),n.gpsValid&&n.status===t.Running&&n.timeSinceLog>5&&(n.timeSinceLog=0,function(t){t.fileWritten||(t.file.write(["timestamp","latitude","longitude","altitude","duration","distance","heartrate","steps"].join(",")+"\n"),t.fileWritten=!0),t.file.write([Date.now().toFixed(0),t.lat.toFixed(6),t.lon.toFixed(6),t.alt.toFixed(2),t.duration.toFixed(0),t.distance.toFixed(2),t.hr.toFixed(0),t.steps.toFixed(0)].join(",")+"\n")}(n))}(o,n)),Bangle.setGPSPower(1),function(t){Bangle.on("HRM",n=>function(t,n){if(0===n.confidence)return;const e=n.bpm-t.hr,i=Math.abs(e)+101-n.confidence,s=t.hrError/(t.hrError+i)||0;t.hr+=e*s,t.hrError+=(i-t.hrError)*s}(t,n)),Bangle.setHRMPower(1)}(r),function(n){Bangle.on("step",()=>function(n){n.status===t.Running&&(n.steps+=1)}(n))}(r),function(t){Bangle.loadWidgets(),Bangle.on("lcdPower",n=>{t.drawing=n,n&&s(t)}),s(t)}(r),setWatch(()=>a(r),BTN1,{repeat:!0,edge:"falling"}),setWatch(()=>function(n){n.status===t.Paused&&function(t){t.duration=0,t.distance=0,t.speed=0,t.steps=0,t.cadence=0}(n),n.status===t.Running?n.status=t.Paused:n.status=t.Stopped,i(n)}(r),BTN3,{repeat:!0,edge:"falling"})}(); diff --git a/apps/banglerun/banglerun.png b/apps/banglerun/banglerun.png deleted file mode 100644 index bf2cd8af3..000000000 Binary files a/apps/banglerun/banglerun.png and /dev/null differ diff --git a/apps/banglerun/interface.html b/apps/banglerun/interface.html deleted file mode 100644 index 6388d3b65..000000000 --- a/apps/banglerun/interface.html +++ /dev/null @@ -1,217 +0,0 @@ - -
- - - - - - - - - diff --git a/apps/banglerun/jasmine.json b/apps/banglerun/jasmine.json deleted file mode 100644 index 813363b27..000000000 --- a/apps/banglerun/jasmine.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "spec_dir": "test", - "spec_files": [ - "**/*.spec.ts" - ] -} \ No newline at end of file diff --git a/apps/banglerun/metadata.json b/apps/banglerun/metadata.json deleted file mode 100644 index d66441c8d..000000000 --- a/apps/banglerun/metadata.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "id": "banglerun", - "name": "BangleRun", - "shortName": "BangleRun", - "version": "0.10", - "description": "An app for running sessions. Displays info and logs your run for later viewing.", - "icon": "banglerun.png", - "tags": "run,running,fitness,outdoors", - "supports": ["BANGLEJS"], - "interface": "interface.html", - "allow_emulator": false, - "storage": [ - {"name":"banglerun.app.js","url":"app.js"}, - {"name":"banglerun.img","url":"app-icon.js","evaluate":true} - ] -} diff --git a/apps/banglerun/package.json b/apps/banglerun/package.json deleted file mode 100644 index 1f5cc677b..000000000 --- a/apps/banglerun/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "banglerun", - "version": "0.5.0", - "description": "Bangle.js app for running sessions", - "main": "app.js", - "types": "app.d.ts", - "scripts": { - "build": "rollup -c", - "test": "ts-node -P tsconfig.spec.json node_modules/jasmine/bin/jasmine --config=jasmine.json" - }, - "author": { - "name": "Stefano Baldan", - "email": "singintime@gmail.com" - }, - "license": "ISC", - "devDependencies": { - "@rollup/plugin-typescript": "^4.1.1", - "@types/jasmine": "^3.5.10", - "jasmine": "^3.5.0", - "rollup": "^2.10.2", - "rollup-plugin-terser": "^5.3.0", - "terser": "^4.7.0", - "ts-node": "^8.10.2", - "tslib": "^2.0.0", - "typescript": "^3.9.2" - } -} diff --git a/apps/banglerun/rollup.config.js b/apps/banglerun/rollup.config.js deleted file mode 100644 index f7027eb2b..000000000 --- a/apps/banglerun/rollup.config.js +++ /dev/null @@ -1,15 +0,0 @@ -import typescript from '@rollup/plugin-typescript'; -import { terser } from 'rollup-plugin-terser'; - -export default { - input: './src/app.ts', - output: { - dir: '.', - format: 'iife', - name: 'banglerun' - }, - plugins: [ - typescript(), - terser(), - ] -}; diff --git a/apps/banglerun/src/activity.ts b/apps/banglerun/src/activity.ts deleted file mode 100644 index c1a01f30b..000000000 --- a/apps/banglerun/src/activity.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { draw } from './display'; -import { initLog } from './log'; -import { ActivityStatus, AppState } from './state'; - -function startActivity(state: AppState): void { - if (state.status === ActivityStatus.Stopped) { - initLog(state); - } - - if (state.status === ActivityStatus.Running) { - state.status = ActivityStatus.Paused; - } else { - state.status = ActivityStatus.Running; - } - - draw(state); -} - -function stopActivity(state: AppState): void { - if (state.status === ActivityStatus.Paused) { - clearActivity(state); - } - - if (state.status === ActivityStatus.Running) { - state.status = ActivityStatus.Paused; - } else { - state.status = ActivityStatus.Stopped; - } - - draw(state); -} - -function clearActivity(state: AppState): void { - state.duration = 0; - state.distance = 0; - state.speed = 0; - state.steps = 0; - state.cadence = 0; -} - -export { clearActivity, startActivity, stopActivity }; diff --git a/apps/banglerun/src/app.ts b/apps/banglerun/src/app.ts deleted file mode 100644 index 7093e24e0..000000000 --- a/apps/banglerun/src/app.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { startActivity, stopActivity } from './activity'; -import { initDisplay } from './display'; -import { initGps } from './gps'; -import { initHrm } from './hrm'; -import { initState } from './state'; -import { initStep } from './step'; - -declare var BTN1: any; -declare var BTN3: any; -declare var setWatch: any; - -const appState = initState(); - -initGps(appState); -initHrm(appState); -initStep(appState); -initDisplay(appState); - -setWatch(() => startActivity(appState), BTN1, { repeat: true, edge: 'falling' }); -setWatch(() => stopActivity(appState), BTN3, { repeat: true, edge: 'falling' }); diff --git a/apps/banglerun/src/display.ts b/apps/banglerun/src/display.ts deleted file mode 100644 index 528890c35..000000000 --- a/apps/banglerun/src/display.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { ActivityStatus, AppState } from './state'; - -declare var Bangle: any; -declare var g: any; - -const STATUS_COLORS = { - 'STOP': 0xF800, - 'PAUSE': 0xFFE0, - 'RUN': 0x07E0, -} - -function initDisplay(state: AppState): void { - Bangle.loadWidgets(); - Bangle.on('lcdPower', (on: boolean) => { - state.drawing = on; - if (on) { - drawAll(state); - } - }); - drawAll(state); -} - -function drawBackground(): void { - g.clear(); - g.setColor(0xC618); - g.setFont('6x8', 2); - g.setFontAlign(0, -1, 0); - g.drawString('DIST (KM)', 60, 32); - g.drawString('TIME', 172, 32); - g.drawString('PACE', 60, 92); - g.drawString('HEART', 172, 92); - g.drawString('STEPS', 60, 152); - g.drawString('CADENCE', 172, 152); -} - -function drawValue(value: string, x: number, y: number) { - g.setColor(0x0000); - g.fillRect(x - 60, y, x + 60, y + 30); - g.setColor(0xFFFF); - g.drawString(value, x, y); -} - -function draw(state: AppState): void { - g.setFontVector(30); - g.setFontAlign(0, -1, 0); - - drawValue(formatDistance(state.distance), 60, 55); - drawValue(formatTime(state.duration), 172, 55); - drawValue(formatPace(state.speed), 60, 115); - drawValue(state.hr.toFixed(0), 172, 115); - drawValue(state.steps.toFixed(0), 60, 175); - drawValue(state.cadence.toFixed(0), 172, 175); - - g.setFont('6x8', 2); - - g.setColor(state.gpsValid ? 0x07E0 : 0xF800); - g.fillRect(0, 216, 80, 240); - g.setColor(0x0000); - g.drawString('GPS', 40, 220); - - g.setColor(0xFFFF); - g.fillRect(80, 216, 160, 240); - g.setColor(0x0000); - g.drawString(formatClock(new Date()), 120, 220); - - g.setColor(STATUS_COLORS[state.status]); - g.fillRect(160, 216, 230, 240); - g.setColor(0x0000); - g.drawString(state.status, 200, 220); - - g.setFont("6x8").setFontAlign(0,0,1).setColor(-1); - if (state.status === ActivityStatus.Paused) { - g.drawString("START",236,60,1).drawString(" CLEAR ",236,180,1); - } else if (state.status === ActivityStatus.Running) { - g.drawString(" PAUSE ",236,60,1).drawString(" PAUSE ",236,180,1); - } else { - g.drawString("START",236,60,1).drawString(" ",236,180,1); - } -} - -function drawAll(state: AppState) { - drawBackground(); - draw(state); - Bangle.drawWidgets(); -} - -function formatClock(date: Date): string { - return ('0' + date.getHours()).substr(-2) + ':' + ('0' + date.getMinutes()).substr(-2); -} - -function formatDistance(meters: number): string { - return (meters / 1000).toFixed(2); -} - -function formatPace(speed: number): string { - if (speed < 0.1667) { - return `__'__"`; - } - const pace = Math.round(1000 / speed); - const min = Math.floor(pace / 60); - const sec = pace % 60; - return ('0' + min).substr(-2) + `'` + ('0' + sec).substr(-2) + `"`; -} - -function formatTime(time: number): string { - const seconds = Math.round(time); - const hrs = Math.floor(seconds / 3600); - const min = Math.floor(seconds / 60) % 60; - const sec = seconds % 60; - return (hrs ? hrs + ':' : '') + ('0' + min).substr(-2) + `:` + ('0' + sec).substr(-2); -} - -export { - draw, - drawAll, - drawBackground, - drawValue, - formatClock, - formatDistance, - formatPace, - formatTime, - initDisplay, -}; diff --git a/apps/banglerun/src/gps.ts b/apps/banglerun/src/gps.ts deleted file mode 100644 index 1886ecfb2..000000000 --- a/apps/banglerun/src/gps.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { draw } from './display'; -import { updateLog } from './log'; -import { ActivityStatus, AppState } from './state'; - -declare var Bangle: any; - -interface GpsEvent { - lat: number; - lon: number; - alt: number; - speed: number; - hdop: number; - fix: number; -} - -const EARTH_RADIUS = 6371008.8; - -function initGps(state: AppState): void { - Bangle.on('GPS', (gps: GpsEvent) => readGps(state, gps)); - Bangle.setGPSPower(1); -} - -function readGps(state: AppState, gps: GpsEvent): void { - state.lat = gps.lat; - state.lon = gps.lon; - state.alt = gps.alt; - state.vel = gps.speed / 3.6; - state.fix = gps.fix; - state.dop = gps.hdop; - state.gpsValid = state.fix > 0; - - updateGps(state); - draw(state); - - /* Only log GPS data every 5 secs if we - have a fix and we're running. */ - if (state.gpsValid && - state.status === ActivityStatus.Running && - state.timeSinceLog > 5) { - state.timeSinceLog = 0; - updateLog(state); - } -} - -function updateGps(state: AppState): void { - const t = Date.now(); - let dt = (t - state.t) / 1000; - if (!isFinite(dt)) dt=0; - state.t = t; - state.timeSinceLog += dt; - - if (state.status === ActivityStatus.Running) { - state.duration += dt; - } - - if (!state.gpsValid) { - return; - } - - const r = EARTH_RADIUS + state.alt; - const lat = state.lat * Math.PI / 180; - const lon = state.lon * Math.PI / 180; - const x = r * Math.cos(lat) * Math.cos(lon); - const y = r * Math.cos(lat) * Math.sin(lon); - const z = r * Math.sin(lat); - - if (!state.x) { - state.x = x; - state.y = y; - state.z = z; - return; - } - - const dx = x - state.x; - const dy = y - state.y; - const dz = z - state.z; - const dpMag = Math.sqrt(dx * dx + dy * dy + dz * dz); - - state.x = x; - state.y = y; - state.z = z; - - if (state.status === ActivityStatus.Running) { - state.distance += dpMag; - state.speed = (state.distance / state.duration) || 0; - state.cadence = (60 * state.steps / state.duration) || 0; - } -} - -export { initGps, readGps, updateGps }; diff --git a/apps/banglerun/src/hrm.ts b/apps/banglerun/src/hrm.ts deleted file mode 100644 index 08dd237a7..000000000 --- a/apps/banglerun/src/hrm.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { AppState } from './state'; - -interface HrmData { - bpm: number; - confidence: number; - raw: string; -} - -declare var Bangle: any; - -function initHrm(state: AppState) { - Bangle.on('HRM', (hrm: HrmData) => updateHrm(state, hrm)); - Bangle.setHRMPower(1); -} - -function updateHrm(state: AppState, hrm: HrmData) { - if (hrm.confidence === 0) { - return; - } - - const dHr = hrm.bpm - state.hr; - const hrError = Math.abs(dHr) + 101 - hrm.confidence; - const hrGain = (state.hrError / (state.hrError + hrError)) || 0; - - state.hr += dHr * hrGain; - state.hrError += (hrError - state.hrError) * hrGain; -} - -export { initHrm, updateHrm }; diff --git a/apps/banglerun/src/log.ts b/apps/banglerun/src/log.ts deleted file mode 100644 index b6714e407..000000000 --- a/apps/banglerun/src/log.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { AppState } from './state'; - -declare var require: any; - -function initLog(state: AppState): void { - const datetime = new Date().toISOString().replace(/[-:]/g, ''); - const date = datetime.substr(2, 6); - const time = datetime.substr(9, 6); - const filename = `banglerun_${date}_${time}`; - state.file = require('Storage').open(filename, 'w'); - state.fileWritten = false; -} - -function updateLog(state: AppState): void { - if (!state.fileWritten) { - state.file.write([ - 'timestamp', - 'latitude', - 'longitude', - 'altitude', - 'duration', - 'distance', - 'heartrate', - 'steps', - ].join(',') + '\n'); - state.fileWritten = true; - } - state.file.write([ - Date.now().toFixed(0), - state.lat.toFixed(6), - state.lon.toFixed(6), - state.alt.toFixed(2), - state.duration.toFixed(0), - state.distance.toFixed(2), - state.hr.toFixed(0), - state.steps.toFixed(0), - ].join(',') + '\n'); -} - -export { initLog, updateLog }; diff --git a/apps/banglerun/src/state.ts b/apps/banglerun/src/state.ts deleted file mode 100644 index 14ef2dc5d..000000000 --- a/apps/banglerun/src/state.ts +++ /dev/null @@ -1,85 +0,0 @@ -enum ActivityStatus { - Stopped = 'STOP', - Paused = 'PAUSE', - Running = 'RUN', -} - -interface AppState { - // GPS NMEA data - fix: number; - lat: number; - lon: number; - alt: number; - vel: number; - dop: number; - gpsValid: boolean; - - // Absolute position data - x: number; - y: number; - z: number; - // Last fix time - t: number; - // Last time we saved log info - timeSinceLog : number; - - // HRM data - hr: number, - hrError: number, - - // Logger data - file: File; - fileWritten: boolean; - - // Drawing data - drawing: boolean; - - // Activity data - status: ActivityStatus; - duration: number; - distance: number; - speed: number; - steps: number; - cadence: number; -} - -interface File { - read: Function; - write: Function; - erase: Function; -} - -function initState(): AppState { - return { - fix: NaN, - lat: NaN, - lon: NaN, - alt: NaN, - vel: NaN, - dop: NaN, - gpsValid: false, - - x: NaN, - y: NaN, - z: NaN, - t: NaN, - timeSinceLog : 0, - - hr: 60, - hrError: 100, - - file: null, - fileWritten: false, - - drawing: false, - - status: ActivityStatus.Stopped, - duration: 0, - distance: 0, - speed: 0, - steps: 0, - cadence: 0, - } -} - -export { ActivityStatus, AppState, File, initState }; diff --git a/apps/banglerun/src/step.ts b/apps/banglerun/src/step.ts deleted file mode 100644 index c7fcb61ea..000000000 --- a/apps/banglerun/src/step.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ActivityStatus, AppState } from './state'; - -declare var Bangle: any; - -function initStep(state: AppState) { - Bangle.on('step', () => updateStep(state)); -} - -function updateStep(state: AppState) { - if (state.status === ActivityStatus.Running) { - state.steps += 1; - } -} - -export { initStep, updateStep }; diff --git a/apps/banglerun/tsconfig.json b/apps/banglerun/tsconfig.json deleted file mode 100644 index a341a5a5e..000000000 --- a/apps/banglerun/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "compilerOptions": { - "module": "es2015", - "noImplicitAny": true, - "target": "es2015" - }, - "include": [ - "src" - ] -} diff --git a/apps/banglerun/tsconfig.spec.json b/apps/banglerun/tsconfig.spec.json deleted file mode 100644 index 136ae137b..000000000 --- a/apps/banglerun/tsconfig.spec.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "noImplicitAny": true, - "target": "es2015" - }, - "include": [ - "test" - ] -} diff --git a/apps/widChargingStatus/ChangeLog b/apps/widChargingStatus/ChangeLog index 1033c0cd3..5a6db5cb7 100644 --- a/apps/widChargingStatus/ChangeLog +++ b/apps/widChargingStatus/ChangeLog @@ -1 +1,2 @@ 0.01: First release. +0.02: No functional changes, just moved codebase to Typescript. diff --git a/apps/widChargingStatus/metadata.json b/apps/widChargingStatus/metadata.json index f68ccf5b4..573c594e7 100644 --- a/apps/widChargingStatus/metadata.json +++ b/apps/widChargingStatus/metadata.json @@ -2,7 +2,7 @@ "name": "Charging Status", "shortName":"ChargingStatus", "icon": "widget.png", - "version":"0.01", + "version":"0.02", "type": "widget", "description": "A simple widget that shows a yellow lightning icon to indicate whenever the watch is charging. This way one can see the charging status at a glance, no matter which battery widget is being used.", "tags": "widget", diff --git a/apps/widChargingStatus/widget.js b/apps/widChargingStatus/widget.js index 90f9199fa..5d9ea3837 100644 --- a/apps/widChargingStatus/widget.js +++ b/apps/widChargingStatus/widget.js @@ -1,31 +1,33 @@ -(() => { - const icon = require("heatshrink").decompress(atob("ikggMAiEAgYIBmEAg4EB+EAh0AgPggEeCAIEBnwQBAgP+gEP//x///j//8f//k///H//4BYOP/4lBv4bDvwEB4EAvAEBwEAuA7DCAI7BgAQBhEAA")); - const iconWidth = 18; - - function draw() { - g.reset(); - if (Bangle.isCharging()) { - g.setColor("#FD0"); - g.drawImage(icon, this.x + 1, this.y + 1, { - scale: 0.6875 - }); - } - } - - WIDGETS.chargingStatus = { - area: 'tr', - width: Bangle.isCharging() ? iconWidth : 0, - draw: draw, - }; - - Bangle.on('charging', (charging) => { - if (charging) { - Bangle.buzz(); - WIDGETS.chargingStatus.width = iconWidth; - } else { - WIDGETS.chargingStatus.width = 0; - } - Bangle.drawWidgets(); // re-layout widgets - g.flip(); - }); -})(); \ No newline at end of file +"use strict"; +(() => { + const icon = require('heatshrink').decompress(atob('ikggMAiEAgYIBmEAg4EB+EAh0AgPggEeCAIEBnwQBAgP+gEP//x///j//8f//k///H//4BYOP/4lBv4bDvwEB4EAvAEBwEAuA7DCAI7BgAQBhEAA')); + const iconWidth = 18; + function draw() { + g.reset(); + if (Bangle.isCharging()) { + g.setColor('#FD0'); + g.drawImage(icon, this.x + 1, this.y + 1, { + scale: 0.6875, + }); + } + } + WIDGETS.chargingStatus = { + area: 'tr', + width: Bangle.isCharging() ? iconWidth : 0, + draw: draw, + }; + Bangle.on('charging', (charging) => { + const widget = WIDGETS.chargingStatus; + if (widget) { + if (charging) { + Bangle.buzz(); + widget.width = iconWidth; + } + else { + widget.width = 0; + } + Bangle.drawWidgets(); // re-layout widgets + g.flip(); + } + }); +})(); diff --git a/apps/widChargingStatus/widget.ts b/apps/widChargingStatus/widget.ts new file mode 100644 index 000000000..14b4df4a4 --- /dev/null +++ b/apps/widChargingStatus/widget.ts @@ -0,0 +1,38 @@ +(() => { + const icon = require('heatshrink').decompress( + atob( + 'ikggMAiEAgYIBmEAg4EB+EAh0AgPggEeCAIEBnwQBAgP+gEP//x///j//8f//k///H//4BYOP/4lBv4bDvwEB4EAvAEBwEAuA7DCAI7BgAQBhEAA' + ) + ); + const iconWidth = 18; + + function draw(this: { x: number; y: number }) { + g.reset(); + if (Bangle.isCharging()) { + g.setColor('#FD0'); + g.drawImage(icon, this.x + 1, this.y + 1, { + scale: 0.6875, + }); + } + } + + WIDGETS.chargingStatus = { + area: 'tr', + width: Bangle.isCharging() ? iconWidth : 0, + draw: draw, + }; + + Bangle.on('charging', (charging) => { + const widget = WIDGETS.chargingStatus; + if (widget) { + if (charging) { + Bangle.buzz(); + widget.width = iconWidth; + } else { + widget.width = 0; + } + Bangle.drawWidgets(); // re-layout widgets + g.flip(); + } + }); +})(); diff --git a/typescript/.gitignore b/typescript/.gitignore new file mode 100644 index 000000000..630f61ee5 --- /dev/null +++ b/typescript/.gitignore @@ -0,0 +1,2 @@ +./node_modules +!package-lock.json diff --git a/typescript/README.md b/typescript/README.md new file mode 100644 index 000000000..13800aeec --- /dev/null +++ b/typescript/README.md @@ -0,0 +1,29 @@ +# BangleTS + +A generic project setup for compiling apps from Typescript to Bangle.js ready, readable Javascript. +It includes types for _some_ of the modules and globals that are exposed for apps to use. +The goal is to have types for everything, but that will take some time. Feel free to help out by contributing! + +## Using the types + +All currently typed modules can be found in `/typescript/types.globals.d.ts`. +The typing is an ongoing process. If anything is still missing, you can add it! It will automatically be available in your TS files. + +## Compilation + +Install [npm](https://www.npmjs.com/get-npm) and node.js if you haven't already. We recommend using a version manager like nvm, which is also referenced in the linked documentation. +Make sure you are using node version 16 by running `nvm use 16` and npm version ^8 by running `npm -v`. If the latter version is incorrect, run `npm i -g npm@^8`. + +After having installed npm for your platform, open a terminal, and navigate into the `/typescript` folder. Then run: + +``` +npm ci +``` + +to install the project's build tools, and: + +``` +npm run build +``` + +To build all Typescript apps and widgets. The last command will generate the `app.js` files containing the transpiled code for the BangleJS. diff --git a/typescript/package-lock.json b/typescript/package-lock.json new file mode 100644 index 000000000..52be5f98a --- /dev/null +++ b/typescript/package-lock.json @@ -0,0 +1,36 @@ +{ + "name": "Bangle.ts", + "version": "0.0.1", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "Bangle.ts", + "version": "0.0.1", + "devDependencies": { + "typescript": "4.5.2" + } + }, + "node_modules/typescript": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + } + }, + "dependencies": { + "typescript": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "dev": true + } + } +} diff --git a/typescript/package.json b/typescript/package.json new file mode 100644 index 000000000..8cd38ce63 --- /dev/null +++ b/typescript/package.json @@ -0,0 +1,13 @@ +{ + "name": "Bangle.ts", + "description": "Bangle.js Typescript Project Setup and Types", + "author": "Sebastian Di Luzio