Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
336601f
began refactoring ui
TobiasRoeddiger Feb 12, 2026
fb9d08d
open_wearable/lib/widgets/sensors/local_recorder: refactored local re…
DennisMoschina Feb 20, 2026
70bd040
open_wearable/lib/local_recorder: added multiple share and delete opt…
DennisMoschina Feb 20, 2026
70a5179
pubspec.yaml: use v2.3.3 of open earable flutter library
DennisMoschina Feb 20, 2026
f2d7a33
refactor(ui): reduce duplicated device refresh and profile action she…
DennisMoschina Feb 20, 2026
afeb306
refactor(sensor-config): extract profile-matching logic into service …
DennisMoschina Feb 20, 2026
5ea8c78
docs(sensor-config): document sensor profile service API
DennisMoschina Feb 20, 2026
c4c1d88
refactor(homepage): refactored home page to not combine multiple unre…
DennisMoschina Feb 20, 2026
7097ac3
refactor(sensor_configuration): extracted profile widgets into their …
DennisMoschina Feb 20, 2026
2048b25
refactor(device_detail): extracted shared widgets into their own files
DennisMoschina Feb 20, 2026
2ffd3dc
refactor(router): implement GoRouter for navigation and streamline wi…
DennisMoschina Feb 20, 2026
a98c21d
fix battery disconnect listener lifecycle guards
DennisMoschina Feb 20, 2026
02b544b
sync home/settings state when widget inputs change
DennisMoschina Feb 20, 2026
9b73f99
remove duplicate notify calls on wearable disconnect
DennisMoschina Feb 20, 2026
49694fb
open_wearable/lib/widgets/devices/devices_page.dart: enhance modal sh…
DennisMoschina Feb 23, 2026
72f3589
feat(lib/widgets/devices/devices_page.dart): enhance paired device sh…
DennisMoschina Feb 26, 2026
44ed848
add high-level app setup and architecture documentation
DennisMoschina Feb 23, 2026
6f26686
document provider architecture and link module docs
DennisMoschina Feb 23, 2026
2d1d71b
add detailed documentation for core app pages
DennisMoschina Feb 23, 2026
488aea2
add detailed documentation for apps and firmware update pages
DennisMoschina Feb 23, 2026
233fd8d
add IDE docstrings for models and view models
DennisMoschina Feb 23, 2026
0f21703
refactor: improve formatting and readability of WearableDisconnectedE…
DennisMoschina Feb 26, 2026
2b606d5
simplified heart rate tracker app
TobiasRoeddiger Mar 2, 2026
de12756
fix(apps/posture_tracker): fixed loading position for earables
DennisMoschina Mar 2, 2026
c8517f1
feat: add methods to clear cached metadata for devices in WearableSta…
DennisMoschina Mar 9, 2026
934123e
chore: update open_earable_flutter dependency to version 2.3.4
DennisMoschina Mar 9, 2026
69ab32a
refactor: streamline sensor disposal logic in HeartTrackerPage and Po…
DennisMoschina Mar 9, 2026
4e3d07e
fixe lifecycle cleanup issues
o-bagge Mar 6, 2026
e8646e0
fix(view_modles/wearables_provider.dart): fixed fall through in switch
DennisMoschina Mar 9, 2026
93d41d3
fix(view_models/wearables_provider.dart): prevent notifications after…
DennisMoschina Mar 9, 2026
1bde051
feat(workflows): Add CI workflow for building PR artifacts across pla…
DennisMoschina Mar 2, 2026
049e191
feat(workflows): Enhance CI workflow to build Android, Linux, Windows…
DennisMoschina Mar 9, 2026
0b8ceb2
fix(workflows): Update artifact download links in PR comment for clarity
DennisMoschina Mar 9, 2026
13637a1
fix(workflows): Upgrade action versions in PR build workflow for cons…
DennisMoschina Mar 9, 2026
b669b14
feat(settings): add keep app in foreground setting to disable automat…
DennisMoschina Mar 11, 2026
6cd5478
feat(fota): implement wake lock management during firmware update pro…
DennisMoschina Mar 13, 2026
d1d7543
resolve merge conflict
o-bagge Mar 31, 2026
c7b529c
Fixed an iOS BLE state issue that previously required restarting the …
o-bagge Apr 1, 2026
0a73b2f
Merge pull request #224 from OpenEarable/ui-redesign-ios-reconnect-fix
o-bagge Apr 1, 2026
b6c566f
lock app to portrait mode on android and iOS
o-bagge Apr 1, 2026
b4a3f56
Merge pull request #225 from OpenEarable/ui-redesign-fixes
o-bagge Apr 1, 2026
e58e2a0
Improved BLE scanning behavior on Android by preventing scan restarts…
o-bagge Apr 7, 2026
57f7686
remove alphabetical ordering of discovered devices to make it easier …
o-bagge Apr 7, 2026
87eecb2
fix UI bug that caused the discovered device card to increase in heig…
o-bagge Apr 7, 2026
eabbd16
disable scan start when pulling down while scan is already in progress
o-bagge Apr 9, 2026
0909bb5
identify sensor streams by wearable and sensor to avoid collisions
DennisMoschina Feb 23, 2026
fa24f28
Fix bugs: On iOS, the app showed that the earable is still connected …
o-bagge Apr 11, 2026
b9ff105
fix some UI bugs: in recordings list, the expand icon and select icon…
o-bagge Apr 11, 2026
ad3dbce
fix top padding of recorder
o-bagge Apr 11, 2026
b6440f4
feat(workflows): add GStreamer dependencies for Linux build
DennisMoschina Mar 10, 2026
654be63
fix(local_recorder_view): added trailing comma
DennisMoschina Apr 13, 2026
e67e441
refactor(ui): share stereo pair setting selector
DennisMoschina Apr 13, 2026
a72e09a
chore(deps): update open_earable_flutter to 2.3.5
DennisMoschina Apr 2, 2026
2f7491d
feat(device-detail): add FOTA capability listener and update handling
DennisMoschina Apr 1, 2026
316d2e4
feat(fota): added possible abort to fota
DennisMoschina Apr 2, 2026
5c0a9c7
feat(fota/slot-info): added slot info page
DennisMoschina Apr 2, 2026
a90aa4f
feat(device-detail): add FOTA slot info support and navigation
DennisMoschina Apr 2, 2026
492c63c
feat(fota): add loop warning for firmware update process
DennisMoschina Apr 2, 2026
b853072
refactor(device_detail_page): simplify fota image slots card
DennisMoschina Apr 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/actions/flutter-prepare/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Flutter Prepare
description: Set up Flutter from .flutter_version and fetch dependencies.

inputs:
app-dir:
description: Path to the Flutter application directory.
required: true

runs:
using: composite
steps:
- name: Read Flutter version
id: flutter_version
shell: bash
run: echo "version=$(cat ${{ inputs.app-dir }}/.flutter_version)" >> "$GITHUB_OUTPUT"

- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
flutter-version: ${{ steps.flutter_version.outputs.version }}
cache: true

- name: Install dependencies
shell: bash
working-directory: ${{ inputs.app-dir }}
run: flutter pub get
216 changes: 216 additions & 0 deletions .github/workflows/pr_build_all_platforms.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
name: Build PR Artifacts

on:
pull_request:
types:
- opened
- synchronize
- reopened
- ready_for_review

permissions:
contents: read
pull-requests: write

concurrency:
group: pr-build-artifacts-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

env:
APP_DIR: open_wearable

jobs:
build_android:
name: Build Android
runs-on: ubuntu-latest
outputs:
artifact_id: ${{ steps.upload_android.outputs.artifact-id }}

steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Set up Java
uses: actions/setup-java@v5
with:
distribution: zulu
java-version: "17"
cache: gradle

- name: Set up Flutter project
uses: ./.github/actions/flutter-prepare
with:
app-dir: ${{ env.APP_DIR }}

- name: Build Android APK
working-directory: ${{ env.APP_DIR }}
run: flutter build apk --release

- name: Upload Android APK
id: upload_android
uses: actions/upload-artifact@v6
with:
name: android-apk
path: open_wearable/build/app/outputs/flutter-apk/app-release.apk
if-no-files-found: error

build_linux:
name: Build Linux
runs-on: ubuntu-latest
outputs:
artifact_id: ${{ steps.upload_linux.outputs.artifact-id }}

steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Install Linux build dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
clang \
cmake \
libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev \
gstreamer1.0-plugins-base \
libgtk-3-dev \
ninja-build \
pkg-config

- name: Set up Flutter project
uses: ./.github/actions/flutter-prepare
with:
app-dir: ${{ env.APP_DIR }}

- name: Build Linux bundle
working-directory: ${{ env.APP_DIR }}
run: flutter build linux --release

- name: Upload Linux bundle
id: upload_linux
uses: actions/upload-artifact@v6
with:
name: linux-bundle
path: open_wearable/build/linux/x64/release/bundle
if-no-files-found: error

build_windows:
name: Build Windows
runs-on: windows-latest
outputs:
artifact_id: ${{ steps.upload_windows.outputs.artifact-id }}

steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Set up Flutter project
uses: ./.github/actions/flutter-prepare
with:
app-dir: ${{ env.APP_DIR }}

- name: Build Windows runner
working-directory: ${{ env.APP_DIR }}
run: flutter build windows --release

- name: Upload Windows runner
id: upload_windows
uses: actions/upload-artifact@v6
with:
name: windows-runner
path: open_wearable/build/windows/x64/runner/Release
if-no-files-found: error

build_web:
name: Build Web
runs-on: ubuntu-latest
outputs:
artifact_id: ${{ steps.upload_web.outputs.artifact-id }}

steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Set up Flutter project
uses: ./.github/actions/flutter-prepare
with:
app-dir: ${{ env.APP_DIR }}

- name: Build Web bundle
working-directory: ${{ env.APP_DIR }}
run: flutter build web --release

- name: Upload Web bundle
id: upload_web
uses: actions/upload-artifact@v6
with:
name: web-bundle
path: open_wearable/build/web
if-no-files-found: error

comment_artifact_links:
name: Comment Artifact Links
runs-on: ubuntu-latest
needs:
- build_android
- build_linux
- build_windows
- build_web
if: always()

steps:
- name: Post or update PR comment with artifact links
uses: actions/github-script@v8
env:
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
ANDROID_ARTIFACT_ID: ${{ needs.build_android.outputs.artifact_id }}
LINUX_ARTIFACT_ID: ${{ needs.build_linux.outputs.artifact_id }}
WINDOWS_ARTIFACT_ID: ${{ needs.build_windows.outputs.artifact_id }}
WEB_ARTIFACT_ID: ${{ needs.build_web.outputs.artifact_id }}
with:
script: |
const marker = '<!-- pr-build-artifacts -->';
const prNumber = context.payload.pull_request.number;
const runUrl = process.env.RUN_URL;
const repoUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}`;
const linkFor = (id) => id
? `${repoUrl}/actions/runs/${context.runId}/artifacts/${id}`
: runUrl;

const body = `${marker}
### PR Build Artifacts
- Android APK: [Download Android build](${linkFor(process.env.ANDROID_ARTIFACT_ID)})
- Linux Bundle: [Download Linux build](${linkFor(process.env.LINUX_ARTIFACT_ID)})
- Windows Runner: [Download Windows build](${linkFor(process.env.WINDOWS_ARTIFACT_ID)})
- Web Bundle: [Download Web build](${linkFor(process.env.WEB_ARTIFACT_ID)})

Full workflow run: ${runUrl}`;

const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
});

const previous = comments.find(
(comment) =>
comment.user.type === 'Bot' &&
comment.body &&
comment.body.includes(marker)
);

if (previous) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: previous.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body,
});
}
32 changes: 22 additions & 10 deletions open_wearable/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
# open_wearable
# OpenWearable App Module

A new Flutter project.
Flutter application module for the OpenEarable app.

## Getting Started
## Documentation

This project is a starting point for a Flutter application.
High-level architecture and state-management docs live in [`docs/`](./docs/README.md).

A few resources to get you started if this is your first Flutter project:
- [App Setup and Architecture](./docs/app-setup.md)
- [State and Providers](./docs/state-and-providers.md)

- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
## Development Quick Start

For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
1. Install Flutter (stable channel).
2. From this folder (`open_wearable/`), fetch dependencies:
```bash
flutter pub get
```
3. Run on a connected device/emulator:
```bash
flutter run
```

## Notes

- Core app bootstrap is in `lib/main.dart`.
- Route definitions are in `lib/router.dart`.
- High-level feature state is primarily under `lib/view_models/`.
2 changes: 1 addition & 1 deletion open_wearable/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:label="OpenWearable" android:name="${applicationName}" android:icon="@mipmap/ic_launcher" android:enableOnBackInvokedCallback="true">
<activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" android:taskAffinity="" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">
<activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" android:taskAffinity="" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize" android:screenOrientation="portrait">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
package edu.kit.teco.openWearable

import android.content.Intent
import android.provider.Settings
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity: FlutterActivity()
class MainActivity : FlutterActivity() {
companion object {
private const val SYSTEM_SETTINGS_CHANNEL = "edu.kit.teco.open_wearable/system_settings"
}

override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)

MethodChannel(
flutterEngine.dartExecutor.binaryMessenger,
SYSTEM_SETTINGS_CHANNEL,
).setMethodCallHandler { call, result ->
if (call.method == "openBluetoothSettings") {
try {
val intent = Intent(Settings.ACTION_BLUETOOTH_SETTINGS).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
startActivity(intent)
result.success(true)
} catch (_: Exception) {
result.success(false)
}
} else {
result.notImplemented()
}
}
}
}
21 changes: 21 additions & 0 deletions open_wearable/docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# OpenWearable App Documentation

This folder contains high-level documentation for the Flutter app in `open_wearable/`.

## Documents

- [App Setup and Architecture](./app-setup.md)
- Startup flow, dependency initialization, routing, UI shell, and lifecycle handling.
- [State and Providers](./state-and-providers.md)
- How top-level providers are wired, how per-device providers are created, and how data flows from wearables to UI.
- [Page Documentation](./pages/README.md)
- Detailed page-by-page contracts: needs, behavior, and outputs.

## Suggested Reading Order

1. [App Setup and Architecture](./app-setup.md)
2. [State and Providers](./state-and-providers.md)

## Scope

These docs are intentionally focused on app-level behavior and state handling. They are not API references for `open_earable_flutter`.
Loading
Loading