Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
400dee57d4
|
|||
| b4ff5884b9 | |||
| beccfa05b3 |
+51
@@ -0,0 +1,51 @@
|
||||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.build/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
.swiftpm/
|
||||
migrate_working_dir/
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# The .vscode folder contains launch configuration and tasks you configure in
|
||||
# VS Code which you may wish to be included in version control, so this line
|
||||
# is commented out by default.
|
||||
#.vscode/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
**/doc/api/
|
||||
**/ios/Flutter/.last_build_id
|
||||
.dart_tool/
|
||||
.flutter-plugins-dependencies
|
||||
.pub-cache/
|
||||
.pub/
|
||||
/build/
|
||||
/coverage/
|
||||
|
||||
# Symbolication related
|
||||
app.*.symbols
|
||||
|
||||
# Obfuscation related
|
||||
app.*.map.json
|
||||
|
||||
# Android Studio will place build artifacts here
|
||||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
|
||||
.flutter-plugins-dependencies
|
||||
android/key.properties
|
||||
windows/installer/*
|
||||
bugreport*
|
||||
!downloads/*
|
||||
@@ -0,0 +1,30 @@
|
||||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: "2c9eb20739dfec95e2c74bd3dfa4601b0a8a36aa"
|
||||
channel: "stable"
|
||||
|
||||
project_type: app
|
||||
|
||||
# Tracks metadata for the flutter migrate command
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: 2c9eb20739dfec95e2c74bd3dfa4601b0a8a36aa
|
||||
base_revision: 2c9eb20739dfec95e2c74bd3dfa4601b0a8a36aa
|
||||
- platform: windows
|
||||
create_revision: 2c9eb20739dfec95e2c74bd3dfa4601b0a8a36aa
|
||||
base_revision: 2c9eb20739dfec95e2c74bd3dfa4601b0a8a36aa
|
||||
|
||||
# User provided section
|
||||
|
||||
# List of Local paths (relative to this file) that should be
|
||||
# ignored by the migrate tool.
|
||||
#
|
||||
# Files that are not part of the templates will be ignored by default.
|
||||
unmanaged_files:
|
||||
- 'lib/main.dart'
|
||||
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||
@@ -1,6 +1,6 @@
|
||||
# BusyLight Buddy
|
||||
|
||||
Multiplatform Flutter app to control your DIY [BusyLight](https://github.com/igox/busylight) (ESP32 + MicroPython + Microdot).
|
||||
Multiplatform Flutter app to control your DIY [BusyLight](https://code.igox.org/iGoX/busylight) (ESP32 + MicroPython + Microdot).
|
||||
|
||||
Supports **iOS**, **ipadOS**, **Android**, **macOS**, and **Windows**.
|
||||
|
||||
@@ -8,10 +8,10 @@ Supports **iOS**, **ipadOS**, **Android**, **macOS**, and **Windows**.
|
||||
|
||||
## Downloads
|
||||
|
||||
[](https://github.com/igox/busylight-buddy/releases/download/v0.0.1/BusyLight-Buddy-Installer.exe)
|
||||
[](https://github.com/igox/busylight-buddy/releases/download/v0.0.1/org.igox.apps.android.busylight-buddy-release.apk)
|
||||
[](https://code.igox.org/iGoX/busylight-buddy/releases/download/v0.0.1/BusyLight-Buddy-Installer.exe)
|
||||
[](https://code.igox.org/iGoX/busylight-buddy/releases/download/v0.0.1/org.igox.apps.android.busylight-buddy-release.apk)
|
||||
|
||||
Or browse all releases on the [Releases page](https://github.com/igox/busylight-buddy/releases).
|
||||
Or browse all releases on the [Releases page](https://code.igox.org/iGoX/busylight-buddy/releases).
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<application
|
||||
android:label="BusyLight Buddy"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:usesCleartextTraffic="true">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
|
||||
@@ -149,6 +149,11 @@ final colorProvider = StateNotifierProvider<ColorNotifier, BusylightColor>(
|
||||
},
|
||||
);
|
||||
|
||||
// ── Connection lost indicator ─────────────────────────────────────────────────
|
||||
// Set to true by the polling notifier when a poll fails, false on success.
|
||||
|
||||
final connectionLostProvider = StateProvider<bool>((_) => false);
|
||||
|
||||
// ── Background polling ────────────────────────────────────────────────────────
|
||||
// Periodically pulls status + color from the device and silently updates state.
|
||||
|
||||
@@ -181,8 +186,11 @@ class PollingNotifier extends StateNotifier<void> {
|
||||
_ref.read(busylightStatusProvider.notifier).setLocalStatus(status);
|
||||
_ref.read(colorProvider.notifier).silentSet(color);
|
||||
_ref.read(brightnessProvider.notifier).silentSet(color.brightness);
|
||||
// Connection restored — clear the lost flag
|
||||
_ref.read(connectionLostProvider.notifier).state = false;
|
||||
} catch (_) {
|
||||
// Silently ignore poll errors — connection issues are shown on manual refresh
|
||||
// Signal connectivity issue to the UI
|
||||
_ref.read(connectionLostProvider.notifier).state = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -122,6 +122,7 @@ class _BodyState extends ConsumerState<_Body> {
|
||||
final brightness = ref.watch(brightnessProvider);
|
||||
final color = ref.watch(colorProvider);
|
||||
final presets = ref.watch(presetsProvider);
|
||||
final connectionLost = ref.watch(connectionLostProvider);
|
||||
|
||||
final status = statusAsync.valueOrNull ?? BusylightStatus.off;
|
||||
final displayColor = _statusColor(status, color);
|
||||
@@ -129,7 +130,7 @@ class _BodyState extends ConsumerState<_Body> {
|
||||
return ListView(
|
||||
padding: const EdgeInsets.all(24),
|
||||
children: [
|
||||
// Live color preview dot
|
||||
// Live color preview dot — shows wifi-off icon when connection lost
|
||||
Center(
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 400),
|
||||
@@ -137,10 +138,12 @@ class _BodyState extends ConsumerState<_Body> {
|
||||
height: 100,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: status == BusylightStatus.off
|
||||
color: connectionLost
|
||||
? Colors.grey.shade900
|
||||
: status == BusylightStatus.off
|
||||
? Colors.grey.shade900
|
||||
: displayColor.withOpacity(brightness),
|
||||
boxShadow: status != BusylightStatus.off
|
||||
boxShadow: (!connectionLost && status != BusylightStatus.off)
|
||||
? [BoxShadow(
|
||||
color: displayColor.withOpacity(0.5 * brightness),
|
||||
blurRadius: 40,
|
||||
@@ -148,13 +151,20 @@ class _BodyState extends ConsumerState<_Body> {
|
||||
)]
|
||||
: null,
|
||||
),
|
||||
child: connectionLost
|
||||
? const Icon(Icons.wifi_off, color: Colors.grey, size: 36)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Center(
|
||||
child: Text(
|
||||
status.label.toUpperCase(),
|
||||
style: const TextStyle(color: Colors.grey, letterSpacing: 2, fontSize: 13),
|
||||
connectionLost ? 'NO CONNECTION' : status.label.toUpperCase(),
|
||||
style: TextStyle(
|
||||
color: connectionLost ? Colors.red.shade700 : Colors.grey,
|
||||
letterSpacing: 2,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 36),
|
||||
@@ -177,9 +187,11 @@ class _BodyState extends ConsumerState<_Body> {
|
||||
BusylightStatus.off,
|
||||
].map((s) => StatusButton(
|
||||
status: s,
|
||||
isActive: status == s,
|
||||
isActive: !connectionLost && status == s,
|
||||
isPending: _pendingStatus == s,
|
||||
onTap: _pendingStatus == null ? () => _setStatus(s) : () {},
|
||||
onTap: (!connectionLost && _pendingStatus == null)
|
||||
? () => _setStatus(s)
|
||||
: () {},
|
||||
)).toList(),
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
@@ -188,7 +200,7 @@ class _BodyState extends ConsumerState<_Body> {
|
||||
_PresetsScroller(
|
||||
presets: presets,
|
||||
pendingPresetId: _pendingPresetId,
|
||||
onPresetTap: (_pendingStatus == null && _pendingPresetId == null)
|
||||
onPresetTap: (!connectionLost && _pendingStatus == null && _pendingPresetId == null)
|
||||
? _applyPreset
|
||||
: (_) {},
|
||||
onPresetDelete: (preset) => ref.read(presetsProvider.notifier).remove(preset.id),
|
||||
|
||||
@@ -330,14 +330,10 @@
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
|
||||
Reference in New Issue
Block a user