update
Some checks failed
xiao_pet_tracker / semantic-pull-request (push) Failing after 0s
xiao_pet_tracker / build (push) Failing after 0s
xiao_pet_tracker / spell-check (push) Failing after 0s

This commit is contained in:
baldeau 2024-11-12 13:57:14 +01:00
parent e9ff329e2e
commit 12f8631c0f
40 changed files with 1649 additions and 209 deletions

19
.nvim.lua Normal file
View File

@ -0,0 +1,19 @@
require("flutter-tools").setup_project({
{
name = "Development",
flavor = "development",
target = "lib/main_development.dart",
},
{
name = "Development Simulator",
flavor = "development",
target = "lib/main_development.dart",
device = "658DAB68-40FB-4DEA-8C0B-C92451326570",
},
{
name = "Production",
flavor = "production",
target = "lib/main_production.dart",
device = "658DAB68-40FB-4DEA-8C0B-C92451326570",
},
})

View File

@ -51,7 +51,8 @@ android {
applicationId "com.example.verygoodcore.xiao_pet_tracker"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion flutter.minSdkVersion
// ObjectBox Sync requires at least SDK 21 (Android 5.0)
minSdkVersion 21
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName

View File

@ -32,5 +32,7 @@
</application>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
</manifest>

View File

@ -2,20 +2,27 @@ PODS:
- Flutter (1.0.0)
- flutter_blue_plus (0.0.1):
- Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_blue_plus (from `.symlinks/plugins/flutter_blue_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
flutter_blue_plus:
:path: ".symlinks/plugins/flutter_blue_plus/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
SPEC CHECKSUMS:
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_blue_plus: 4837da7d00cf5d441fdd6635b3a57f936778ea96
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796

View File

@ -1 +1,20 @@
export 'view/app.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:xiao_pet_tracker/app/view/app.dart';
import 'package:xiao_pet_tracker/xiao_connector/cubit/xiao_connector_cubit.dart';
class App extends StatelessWidget {
const App({super.key});
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(
create: (BuildContext context) => XiaoConnectorCubit()..init(),
),
],
child: const AppView(),
);
}
}

View File

@ -2,19 +2,22 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_blue_plus_windows/flutter_blue_plus_windows.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:forui/forui.dart';
import 'package:xiao_pet_tracker/app_router/app_router.dart';
import 'package:xiao_pet_tracker/bootstrap.dart';
import 'package:xiao_pet_tracker/home/view/home_page.dart';
import 'package:xiao_pet_tracker/l10n/l10n.dart';
import 'package:xiao_pet_tracker/screens/bluetooth_off_screen.dart';
class App extends StatefulWidget {
const App({super.key});
class AppView extends StatefulWidget {
const AppView({super.key});
@override
State<App> createState() => _AppState();
State<AppView> createState() => _AppState();
}
class _AppState extends State<App> {
class _AppState extends State<AppView> {
BluetoothAdapterState _adapterState = BluetoothAdapterState.unknown;
late StreamSubscription<BluetoothAdapterState> _adapterStateStateSubscription;
@ -45,11 +48,25 @@ class _AppState extends State<App> {
adapterState: _adapterState,
);
return ShadApp.material(
localizationsDelegates: AppLocalizations.localizationsDelegates,
return MaterialApp.router(
title: 'Xiao Pet Tracker',
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
// localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
navigatorObservers: [BluetoothAdapterStateObserver()],
home: screen,
routerConfig: getIt<AppRouter>().config(),
theme: ThemeData(),
darkTheme: ThemeData.dark(),
builder: (context, child) => FTheme(
data: MediaQuery.of(context).platformBrightness == Brightness.light
? FThemes.zinc.light
: FThemes.zinc.dark,
child: child!,
),
);
}
}
@ -63,13 +80,14 @@ class BluetoothAdapterStateObserver extends NavigatorObserver {
super.didPush(route, previousRoute);
if (route.settings.name == '/DeviceScreen') {
// Start listening to Bluetooth state changes when a new route is pushed
_adapterStateSubscription ??=
FlutterBluePlus.adapterState.listen((state) {
if (state != BluetoothAdapterState.on) {
// Pop the current route if Bluetooth is off
navigator?.pop();
}
});
_adapterStateSubscription ??= FlutterBluePlus.adapterState.listen(
(state) {
if (state != BluetoothAdapterState.on) {
// Pop the current route if Bluetooth is off
navigator?.pop();
}
},
);
}
}

View File

@ -0,0 +1,88 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:forui/forui.dart';
import 'package:xiao_pet_tracker/app_router/app_router.gr.dart';
@AutoRouterConfig()
class AppRouter extends RootStackRouter {
@override
RouteType get defaultRouteType => const RouteType.material();
@override
List<AutoRoute> get routes => [
AutoRoute(
page: MainRoute.page,
path: '/',
children: [
AutoRoute(
page: HomeRoute.page,
),
AutoRoute(
page: XiaoConnectorRoute.page,
),
AutoRoute(
page: SettingsRoute.page,
),
],
)
];
}
@RoutePage()
class MainPage extends StatelessWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context) {
return AutoTabsScaffold(
// transitionBuilder: (context, child, animation) => AnimatedBuilder(
// animation: animation,
// child: child,
// // builder: (BuildContext context, Widget? child) {
// // const begin = Offset(0.0, 0.1);
// // const end = Offset.zero;
// // final tween = Tween(begin: begin, end: end);
// // final offsetAnimation = animation.drive(tween);
// // return SlideTransition(
// // position: offsetAnimation,
// // child: Transform.scale(
// // alignment: Alignment.bottomCenter,
// // scale: animation.value,
// // child: ClipPath(
// // clipper: CircularRevealClipper(
// // fraction: animation.value,
// // centerAlignment: Alignment.bottomCenter,
// // // centerOffset: centerOffset,
// // // minRadius: minRadius,
// // // maxRadius: maxRadius,
// // ),
// // child: child,
// // ),
// // ),
// // );
// // },
// ),
animationDuration: const Duration(milliseconds: 650),
routes: const [
XiaoConnectorRoute(),
SettingsRoute(),
],
bottomNavigationBuilder: (context, tabsRouter) {
return FBottomNavigationBar(
index: tabsRouter.activeIndex,
onChange: tabsRouter.setActiveIndex,
children: [
FBottomNavigationBarItem(
label: const Text('Home'),
icon: FIcon(FAssets.icons.house),
),
FBottomNavigationBarItem(
label: const Text('Settings'),
icon: FIcon(FAssets.icons.settings),
),
],
);
},
);
}
}

View File

@ -0,0 +1,92 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// **************************************************************************
// AutoRouterGenerator
// **************************************************************************
// ignore_for_file: type=lint
// coverage:ignore-file
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'package:auto_route/auto_route.dart' as _i5;
import 'package:xiao_pet_tracker/app_router/app_router.dart' as _i2;
import 'package:xiao_pet_tracker/home/view/home_page.dart' as _i1;
import 'package:xiao_pet_tracker/settings/view/settings_page.dart' as _i3;
import 'package:xiao_pet_tracker/xiao_connector/view/xiao_connector_page.dart'
as _i4;
/// generated route for
/// [_i1.HomePage]
class HomeRoute extends _i5.PageRouteInfo<void> {
const HomeRoute({List<_i5.PageRouteInfo>? children})
: super(
HomeRoute.name,
initialChildren: children,
);
static const String name = 'HomeRoute';
static _i5.PageInfo page = _i5.PageInfo(
name,
builder: (data) {
return const _i1.HomePage();
},
);
}
/// generated route for
/// [_i2.MainPage]
class MainRoute extends _i5.PageRouteInfo<void> {
const MainRoute({List<_i5.PageRouteInfo>? children})
: super(
MainRoute.name,
initialChildren: children,
);
static const String name = 'MainRoute';
static _i5.PageInfo page = _i5.PageInfo(
name,
builder: (data) {
return const _i2.MainPage();
},
);
}
/// generated route for
/// [_i3.SettingsPage]
class SettingsRoute extends _i5.PageRouteInfo<void> {
const SettingsRoute({List<_i5.PageRouteInfo>? children})
: super(
SettingsRoute.name,
initialChildren: children,
);
static const String name = 'SettingsRoute';
static _i5.PageInfo page = _i5.PageInfo(
name,
builder: (data) {
return const _i3.SettingsPage();
},
);
}
/// generated route for
/// [_i4.XiaoConnectorPage]
class XiaoConnectorRoute extends _i5.PageRouteInfo<void> {
const XiaoConnectorRoute({List<_i5.PageRouteInfo>? children})
: super(
XiaoConnectorRoute.name,
initialChildren: children,
);
static const String name = 'XiaoConnectorRoute';
static _i5.PageInfo page = _i5.PageInfo(
name,
builder: (data) {
return const _i4.XiaoConnectorPage();
},
);
}

View File

@ -3,6 +3,11 @@ import 'dart:developer';
import 'package:bloc/bloc.dart';
import 'package:flutter/widgets.dart';
import 'package:get_it/get_it.dart';
import 'package:xiao_pet_tracker/app_router/app_router.dart';
import 'package:xiao_pet_tracker/objectbox.dart';
final getIt = GetIt.instance;
class AppBlocObserver extends BlocObserver {
const AppBlocObserver();
@ -31,5 +36,9 @@ Future<void> bootstrap(FutureOr<Widget> Function() builder) async {
WidgetsFlutterBinding.ensureInitialized();
final AppRouter appRouter = getIt.registerSingleton(AppRouter());
final ObjectBox objectBox = getIt.registerSingleton(await ObjectBox.create());
runApp(await builder());
}

View File

@ -1,10 +1,11 @@
import 'dart:async';
import 'package:auto_route/auto_route.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blue_plus_windows/flutter_blue_plus_windows.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
@RoutePage()
class HomePage extends StatelessWidget {
const HomePage({super.key});
@ -199,8 +200,8 @@ class _HomeScreenState extends State<HomeScreen> {
// },
// ),
if (_connected) Text('Connected!'),
ShadButton(
enabled: !_isScanning,
ElevatedButton(
// enabled: !_isScanning,
onPressed: () async {
// await Future<void>.delayed(const Duration(seconds: 2));
// onScanPressed();
@ -210,19 +211,19 @@ class _HomeScreenState extends State<HomeScreen> {
onConnectPressed();
}
},
icon: _isScanning
? const SizedBox.square(
dimension: 16,
child: CircularProgressIndicator(),
)
: null,
// icon: _isScanning
// ? const SizedBox.square(
// dimension: 16,
// child: CircularProgressIndicator(),
// )
// : null,
child: _isScanning
? const Text('Please wait')
: _connected
? const Text('Disconnect')
: const Text('Connect'),
),
ShadButton(
ElevatedButton(
onPressed: () async {
print('Toggle LED');
print(_services);
@ -250,7 +251,7 @@ class _HomeScreenState extends State<HomeScreen> {
},
child: Text('Toggle LED'),
),
ShadButton(
ElevatedButton(
onPressed: () async {
print('Toggle LED');
print(_services);
@ -258,21 +259,32 @@ class _HomeScreenState extends State<HomeScreen> {
.where(
(s) =>
s.serviceUuid ==
Guid('a0b40003-926d-4d61-98df-8c5c62ee53b3'),
Guid('4c534d36-4453-3354-5253-657276696365'),
)
.first
.characteristics
.where((c) =>
c.characteristicUuid ==
Guid('a0b40004-926d-4d61-98df-8c5c62ee53b3'))
.where(
(c) =>
c.characteristicUuid ==
Guid('61636365-6c65-7261-7469-6f6e44617461'),
)
.first;
final senseSubscription =
ledService.onValueReceived.listen((value) {
print("UPDATE: ${String.fromCharCodes(value)}");
});
device!.cancelWhenDisconnected(senseSubscription);
await ledService.setNotifyValue(true);
// await ledService.write([1, 2, 3]);
// await Future.delayed(Duration(seconds: 2));
List<int> ledServiceValue = await ledService.read();
print("READ Sense SERVICE: $ledServiceValue");
print(
"READ Sense SERVICE: ${String.fromCharCodes(ledServiceValue)}");
// List<int> ledServiceValue = await ledService.read();
// print("READ Sense SERVICE: $ledServiceValue");
// print(
// "READ Sense SERVICE: ${String.fromCharCodes(ledServiceValue)}");
},
child: Text('Read Sense'),
)

84
lib/objectbox-model.json Normal file
View File

@ -0,0 +1,84 @@
{
"_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.",
"_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.",
"_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.",
"entities": [
{
"id": "2:23371849066855038",
"lastPropertyId": "10:4052938287274443905",
"name": "CapturePoint",
"properties": [
{
"id": "1:9209282349575641428",
"name": "id",
"type": 6,
"flags": 1
},
{
"id": "2:8441629944202144182",
"name": "rotationX",
"type": 9
},
{
"id": "3:3805193742978753321",
"name": "rotationY",
"type": 9
},
{
"id": "4:7632102454091387966",
"name": "rotationZ",
"type": 9
},
{
"id": "5:1175247580397683930",
"name": "accelerationX",
"type": 9
},
{
"id": "6:133552602314920473",
"name": "accelerationY",
"type": 9
},
{
"id": "7:7272664476171529007",
"name": "accelerationZ",
"type": 9
},
{
"id": "9:5697556233714735057",
"name": "type",
"type": 9
},
{
"id": "10:4052938287274443905",
"name": "millisecondsSinceEpoch",
"type": 6
}
],
"relations": []
}
],
"lastEntityId": "2:23371849066855038",
"lastIndexId": "0:0",
"lastRelationId": "0:0",
"lastSequenceId": "0:0",
"modelVersion": 5,
"modelVersionParserMinimum": 5,
"retiredEntityUids": [
6206931177901930822
],
"retiredIndexUids": [],
"retiredPropertyUids": [
696937191447548336,
7375635633551465262,
7972299062087181706,
5044874535120106939,
6473009355337784814,
8948425706967252950,
5134040367670771080,
4879888592430478383,
2890906455219707986
],
"retiredRelationUids": [],
"version": 1
}

18
lib/objectbox.dart Normal file
View File

@ -0,0 +1,18 @@
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
import 'objectbox.g.dart';
class ObjectBox {
late final Store store;
/// Initialization
ObjectBox._create(this.store);
/// Create an instance of ObjectBox to use throughout the app.
static Future<ObjectBox> create() async {
final docsDir = await getApplicationDocumentsDirectory();
final store =
await openStore(directory: p.join(docsDir.path, 'obx-pet-tracker'));
return ObjectBox._create(store);
}
}

242
lib/objectbox.g.dart Normal file
View File

@ -0,0 +1,242 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// This code was generated by ObjectBox. To update it run the generator again
// with `dart run build_runner build`.
// See also https://docs.objectbox.io/getting-started#generate-objectbox-code
// ignore_for_file: camel_case_types, depend_on_referenced_packages
// coverage:ignore-file
import 'dart:typed_data';
import 'package:flat_buffers/flat_buffers.dart' as fb;
import 'package:objectbox/internal.dart'
as obx_int; // generated code can access "internal" functionality
import 'package:objectbox/objectbox.dart' as obx;
import 'package:objectbox_flutter_libs/objectbox_flutter_libs.dart';
import 'xiao_connector/models/capture_point.dart';
export 'package:objectbox/objectbox.dart'; // so that callers only have to import this file
final _entities = <obx_int.ModelEntity>[
obx_int.ModelEntity(
id: const obx_int.IdUid(2, 23371849066855038),
name: 'CapturePoint',
lastPropertyId: const obx_int.IdUid(10, 4052938287274443905),
flags: 0,
properties: <obx_int.ModelProperty>[
obx_int.ModelProperty(
id: const obx_int.IdUid(1, 9209282349575641428),
name: 'id',
type: 6,
flags: 1),
obx_int.ModelProperty(
id: const obx_int.IdUid(2, 8441629944202144182),
name: 'rotationX',
type: 9,
flags: 0),
obx_int.ModelProperty(
id: const obx_int.IdUid(3, 3805193742978753321),
name: 'rotationY',
type: 9,
flags: 0),
obx_int.ModelProperty(
id: const obx_int.IdUid(4, 7632102454091387966),
name: 'rotationZ',
type: 9,
flags: 0),
obx_int.ModelProperty(
id: const obx_int.IdUid(5, 1175247580397683930),
name: 'accelerationX',
type: 9,
flags: 0),
obx_int.ModelProperty(
id: const obx_int.IdUid(6, 133552602314920473),
name: 'accelerationY',
type: 9,
flags: 0),
obx_int.ModelProperty(
id: const obx_int.IdUid(7, 7272664476171529007),
name: 'accelerationZ',
type: 9,
flags: 0),
obx_int.ModelProperty(
id: const obx_int.IdUid(9, 5697556233714735057),
name: 'type',
type: 9,
flags: 0),
obx_int.ModelProperty(
id: const obx_int.IdUid(10, 4052938287274443905),
name: 'millisecondsSinceEpoch',
type: 6,
flags: 0)
],
relations: <obx_int.ModelRelation>[],
backlinks: <obx_int.ModelBacklink>[])
];
/// Shortcut for [obx.Store.new] that passes [getObjectBoxModel] and for Flutter
/// apps by default a [directory] using `defaultStoreDirectory()` from the
/// ObjectBox Flutter library.
///
/// Note: for desktop apps it is recommended to specify a unique [directory].
///
/// See [obx.Store.new] for an explanation of all parameters.
///
/// For Flutter apps, also calls `loadObjectBoxLibraryAndroidCompat()` from
/// the ObjectBox Flutter library to fix loading the native ObjectBox library
/// on Android 6 and older.
Future<obx.Store> openStore(
{String? directory,
int? maxDBSizeInKB,
int? maxDataSizeInKB,
int? fileMode,
int? maxReaders,
bool queriesCaseSensitiveDefault = true,
String? macosApplicationGroup}) async {
await loadObjectBoxLibraryAndroidCompat();
return obx.Store(getObjectBoxModel(),
directory: directory ?? (await defaultStoreDirectory()).path,
maxDBSizeInKB: maxDBSizeInKB,
maxDataSizeInKB: maxDataSizeInKB,
fileMode: fileMode,
maxReaders: maxReaders,
queriesCaseSensitiveDefault: queriesCaseSensitiveDefault,
macosApplicationGroup: macosApplicationGroup);
}
/// Returns the ObjectBox model definition for this project for use with
/// [obx.Store.new].
obx_int.ModelDefinition getObjectBoxModel() {
final model = obx_int.ModelInfo(
entities: _entities,
lastEntityId: const obx_int.IdUid(2, 23371849066855038),
lastIndexId: const obx_int.IdUid(0, 0),
lastRelationId: const obx_int.IdUid(0, 0),
lastSequenceId: const obx_int.IdUid(0, 0),
retiredEntityUids: const [6206931177901930822],
retiredIndexUids: const [],
retiredPropertyUids: const [
696937191447548336,
7375635633551465262,
7972299062087181706,
5044874535120106939,
6473009355337784814,
8948425706967252950,
5134040367670771080,
4879888592430478383,
2890906455219707986
],
retiredRelationUids: const [],
modelVersion: 5,
modelVersionParserMinimum: 5,
version: 1);
final bindings = <Type, obx_int.EntityDefinition>{
CapturePoint: obx_int.EntityDefinition<CapturePoint>(
model: _entities[0],
toOneRelations: (CapturePoint object) => [],
toManyRelations: (CapturePoint object) => {},
getId: (CapturePoint object) => object.id,
setId: (CapturePoint object, int id) {
object.id = id;
},
objectToFB: (CapturePoint object, fb.Builder fbb) {
final rotationXOffset = fbb.writeString(object.rotationX);
final rotationYOffset = fbb.writeString(object.rotationY);
final rotationZOffset = fbb.writeString(object.rotationZ);
final accelerationXOffset = fbb.writeString(object.accelerationX);
final accelerationYOffset = fbb.writeString(object.accelerationY);
final accelerationZOffset = fbb.writeString(object.accelerationZ);
final typeOffset = fbb.writeString(object.type);
fbb.startTable(11);
fbb.addInt64(0, object.id);
fbb.addOffset(1, rotationXOffset);
fbb.addOffset(2, rotationYOffset);
fbb.addOffset(3, rotationZOffset);
fbb.addOffset(4, accelerationXOffset);
fbb.addOffset(5, accelerationYOffset);
fbb.addOffset(6, accelerationZOffset);
fbb.addOffset(8, typeOffset);
fbb.addInt64(9, object.millisecondsSinceEpoch);
fbb.finish(fbb.endTable());
return object.id;
},
objectFromFB: (obx.Store store, ByteData fbData) {
final buffer = fb.BufferContext(fbData);
final rootOffset = buffer.derefObject(0);
final typeParam = const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 20, '');
final rotationXParam = const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 6, '');
final rotationYParam = const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 8, '');
final rotationZParam = const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 10, '');
final accelerationXParam =
const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 12, '');
final accelerationYParam =
const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 14, '');
final accelerationZParam =
const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 16, '');
final millisecondsSinceEpochParam =
const fb.Int64Reader().vTableGetNullable(buffer, rootOffset, 22);
final object = CapturePoint(
type: typeParam,
rotationX: rotationXParam,
rotationY: rotationYParam,
rotationZ: rotationZParam,
accelerationX: accelerationXParam,
accelerationY: accelerationYParam,
accelerationZ: accelerationZParam,
millisecondsSinceEpoch: millisecondsSinceEpochParam)
..id = const fb.Int64Reader().vTableGet(buffer, rootOffset, 4, 0);
return object;
})
};
return obx_int.ModelDefinition(model, bindings);
}
/// [CapturePoint] entity fields to define ObjectBox queries.
class CapturePoint_ {
/// See [CapturePoint.id].
static final id =
obx.QueryIntegerProperty<CapturePoint>(_entities[0].properties[0]);
/// See [CapturePoint.rotationX].
static final rotationX =
obx.QueryStringProperty<CapturePoint>(_entities[0].properties[1]);
/// See [CapturePoint.rotationY].
static final rotationY =
obx.QueryStringProperty<CapturePoint>(_entities[0].properties[2]);
/// See [CapturePoint.rotationZ].
static final rotationZ =
obx.QueryStringProperty<CapturePoint>(_entities[0].properties[3]);
/// See [CapturePoint.accelerationX].
static final accelerationX =
obx.QueryStringProperty<CapturePoint>(_entities[0].properties[4]);
/// See [CapturePoint.accelerationY].
static final accelerationY =
obx.QueryStringProperty<CapturePoint>(_entities[0].properties[5]);
/// See [CapturePoint.accelerationZ].
static final accelerationZ =
obx.QueryStringProperty<CapturePoint>(_entities[0].properties[6]);
/// See [CapturePoint.type].
static final type =
obx.QueryStringProperty<CapturePoint>(_entities[0].properties[7]);
/// See [CapturePoint.millisecondsSinceEpoch].
static final millisecondsSinceEpoch =
obx.QueryIntegerProperty<CapturePoint>(_entities[0].properties[8]);
}

View File

@ -0,0 +1 @@
export 'view/view.dart';

View File

@ -0,0 +1,23 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
@RoutePage()
class SettingsPage extends StatelessWidget {
const SettingsPage({super.key});
@override
Widget build(BuildContext context) {
return const SettingsView();
}
}
class SettingsView extends StatelessWidget {
const SettingsView({super.key});
@override
Widget build(BuildContext context) {
return const Center(
child: Text('Settings'),
);
}
}

View File

@ -0,0 +1 @@
export 'settings_page.dart';

View File

@ -0,0 +1,6 @@
const uuidLSM6DS3TRService = '4c534d36-4453-3354-5253-657276696365';
const uuidAccelerationData = '61636365-6c65-7261-7469-6f6e44617461';
//tempSenseService = [16]byte{0x74, 0x65, 0x6D, 0x70, 0x53, 0x65, 0x6E, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65}
//temperatureSense = [16]byte{0x74, 0x65, 0x6D, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x6E, 0x73, 0x65}

View File

@ -0,0 +1,194 @@
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_blue_plus_windows/flutter_blue_plus_windows.dart';
import 'package:objectbox/objectbox.dart';
import 'package:xiao_pet_tracker/bootstrap.dart';
import 'package:xiao_pet_tracker/objectbox.dart';
import 'package:xiao_pet_tracker/xiao_connector/models/capture_point.dart';
part 'xiao_connector_state.dart';
class XiaoConnectorCubit extends Cubit<XiaoConnectorState> {
XiaoConnectorCubit() : super(const XiaoConnectorState());
late BluetoothDevice device;
List<BluetoothDevice> _systemDevices = [];
List<BluetoothService> _services = [];
late StreamSubscription<List<int>> dataCapturingSubscription;
final ObjectBox _objectBox = getIt<ObjectBox>();
late final Box<CapturePoint> _capturePointsBox;
bool gotRotationX = false;
bool gotRotationY = false;
bool gotRotationZ = false;
bool gotAcceleration = false;
late String _rotX;
late String _rotY;
late String _rotZ;
late String _accel;
Future<void> init() async {
_capturePointsBox = _objectBox.store.box<CapturePoint>();
}
Future<void> connect() async {
emit(state.copyWith(status: XiaoConnectorStatus.loading));
try {
_systemDevices = await FlutterBluePlus.systemDevices([]);
} catch (e) {
emit(state.copyWith(status: XiaoConnectorStatus.failure));
throw Exception('System Devices Error: $e');
}
try {
// scan for devices for 15 seconds
await FlutterBluePlus.startScan(timeout: const Duration(seconds: 15));
} catch (e) {
emit(state.copyWith(status: XiaoConnectorStatus.failure));
throw Exception('Start Scan Error: $e');
}
FlutterBluePlus.scanResults.listen(
(results) async {
for (final r in results) {
if (kDebugMode) {
print(r);
}
// set the xiao sense name
if (r.device.advName == 'Go Bluetooth') {
await FlutterBluePlus.stopScan();
device = r.device;
await device.connect();
try {
_services = await device.discoverServices();
} catch (e) {
emit(state.copyWith(status: XiaoConnectorStatus.failure));
throw Exception('Discover Services Error: $e');
}
device.connectionState
.listen((BluetoothConnectionState blueState) async {
if (blueState == BluetoothConnectionState.disconnected) {
debugPrint('DISCONNECTED!');
emit(state.copyWith(status: XiaoConnectorStatus.initial));
}
});
// device.cancelWhenDisconnected(deviceConnectionStream);
emit(state.copyWith(status: XiaoConnectorStatus.connected));
}
}
},
onDone: () {
debugPrint('DONE');
emit(state.copyWith(status: XiaoConnectorStatus.initial));
},
);
}
Future<void> startCapturing({required String captureType}) async {
final senseService = _services
.where(
(s) => s.serviceUuid == Guid('4c534d36-4453-3354-5253-657276696365'),
)
.first
.characteristics
.where(
(c) =>
c.characteristicUuid ==
Guid('61636365-6c65-7261-7469-6f6e44617461'),
)
.first;
dataCapturingSubscription = senseService.onValueReceived.listen((value) {
debugPrint('UPDATE: $value');
debugPrint('UPDATE: ${String.fromCharCodes(value)}');
final valueAsString = String.fromCharCodes(value);
if (valueAsString.startsWith('rX=')) {
gotRotationX = true;
_rotX = valueAsString.replaceAll('rX=', '');
}
if (valueAsString.startsWith('rY=')) {
gotRotationY = true;
_rotY = valueAsString.replaceAll('rY=', '');
}
if (valueAsString.startsWith('rZ=')) {
gotRotationZ = true;
_rotZ = valueAsString.replaceAll('rZ=', '');
}
if (valueAsString.contains(',')) {
gotAcceleration = true;
_accel = valueAsString;
}
if (gotAcceleration && gotRotationX && gotRotationY && gotRotationZ) {
final accelerations = _accel.split(',');
final capturePoint = CapturePoint(
type: captureType,
rotationX: _rotX,
rotationY: _rotY,
rotationZ: _rotZ,
accelerationX: accelerations[0],
accelerationY: accelerations[1],
accelerationZ: accelerations[2],
millisecondsSinceEpoch: DateTime.now().toUtc().millisecondsSinceEpoch,
);
emit(state.copyWith(lastCapturedPoint: capturePoint));
debugPrint("UPDATED POINT!");
// _writeToObjectBox(capturePoint: capturePoint);
gotRotationX = false;
gotRotationY = false;
gotRotationZ = false;
gotAcceleration = false;
}
});
device.cancelWhenDisconnected(dataCapturingSubscription);
await senseService.setNotifyValue(true);
emit(state.copyWith(status: XiaoConnectorStatus.capturing));
}
Future<void> stopCapturing() async {
await dataCapturingSubscription.cancel();
emit(state.copyWith(status: XiaoConnectorStatus.connected));
}
void _writeToObjectBox({
required CapturePoint capturePoint,
}) {
_capturePointsBox.put(capturePoint);
}
void readFromObjectBox() {
final points = _capturePointsBox.getAll();
for (var i = 0; i < points.length; i++) {
final point = points[i];
debugPrint('Type: ${point.type}');
debugPrint('Id: ${point.id}');
debugPrint('RotX: ${point.rotationX}');
debugPrint('RotY: ${point.rotationY}');
debugPrint('RotZ: ${point.rotationZ}');
debugPrint('AccelX: ${point.accelerationX}');
debugPrint('AccelY: ${point.accelerationY}');
debugPrint('AccelZ: ${point.accelerationZ}');
debugPrint('Date: ${point.millisecondsSinceEpoch}');
}
}
}

View File

@ -0,0 +1,40 @@
part of 'xiao_connector_cubit.dart';
enum XiaoConnectorStatus {
initial,
loading,
connected,
capturing,
failure,
}
extension XiaoConnectorStatusX on XiaoConnectorStatus {
bool get isInitial => this == XiaoConnectorStatus.initial;
bool get isLoading => this == XiaoConnectorStatus.loading;
bool get isConnected => this == XiaoConnectorStatus.connected;
bool get isCapturing => this == XiaoConnectorStatus.capturing;
bool get isFailure => this == XiaoConnectorStatus.failure;
}
final class XiaoConnectorState extends Equatable {
const XiaoConnectorState({
this.status = XiaoConnectorStatus.initial,
this.lastCapturedPoint,
});
final XiaoConnectorStatus status;
final CapturePoint? lastCapturedPoint;
XiaoConnectorState copyWith({
XiaoConnectorStatus? status,
CapturePoint? lastCapturedPoint,
}) {
return XiaoConnectorState(
status: status ?? this.status,
lastCapturedPoint: lastCapturedPoint ?? this.lastCapturedPoint,
);
}
@override
List<Object?> get props => [status, lastCapturedPoint];
}

View File

@ -0,0 +1,28 @@
import 'package:objectbox/objectbox.dart';
@Entity()
class CapturePoint {
CapturePoint({
required this.type,
required this.rotationX,
required this.rotationY,
required this.rotationZ,
required this.accelerationX,
required this.accelerationY,
required this.accelerationZ,
this.millisecondsSinceEpoch,
});
@Id()
int id = 0;
String type;
String rotationX;
String rotationY;
String rotationZ;
String accelerationX;
String accelerationY;
String accelerationZ;
// @Property(type: PropertyType.date)
int? millisecondsSinceEpoch;
}

View File

@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:xiao_pet_tracker/xiao_connector/cubit/xiao_connector_cubit.dart';
class CaptureView extends StatelessWidget {
const CaptureView({super.key});
@override
Widget build(BuildContext context) {
final lastCapturePoint = context
.select((XiaoConnectorCubit cubit) => cubit.state.lastCapturedPoint);
return Scaffold(
appBar: AppBar(
title: const Text('Capturing'),
),
body: SingleChildScrollView(
child: Center(
child: Column(
children: [
ElevatedButton(
onPressed: () {
context.read<XiaoConnectorCubit>().stopCapturing();
},
child: const Text('Stop Capturing'),
),
const Text(
'Last Captured Point',
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(
'${DateTime.fromMillisecondsSinceEpoch(lastCapturePoint?.millisecondsSinceEpoch ?? 0)}'),
const Divider(),
Text('Acceleration X: ${lastCapturePoint?.accelerationX}'),
Text('Acceleration Y: ${lastCapturePoint?.accelerationY}'),
Text('Acceleration Z: ${lastCapturePoint?.accelerationZ}'),
const Divider(),
Text('Rotation X: ${lastCapturePoint?.rotationX}'),
Text('Rotation Y: ${lastCapturePoint?.rotationY}'),
Text('Rotation Z: ${lastCapturePoint?.rotationZ}'),
],
),
),
),
);
}
}

View File

@ -0,0 +1,10 @@
import 'package:flutter/material.dart';
class FailureView extends StatelessWidget {
const FailureView({super.key});
@override
Widget build(BuildContext context) {
return const Text('Failure');
}
}

View File

@ -0,0 +1 @@
export 'xiao_connector_page.dart';

View File

@ -0,0 +1,59 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:xiao_pet_tracker/xiao_connector/cubit/xiao_connector_cubit.dart';
import 'package:xiao_pet_tracker/xiao_connector/view/capture_view.dart';
import 'package:xiao_pet_tracker/xiao_connector/view/failure_view.dart';
@RoutePage()
class XiaoConnectorPage extends StatelessWidget {
const XiaoConnectorPage({super.key});
@override
Widget build(BuildContext context) {
return const XiaoConnectorView();
}
}
class XiaoConnectorView extends StatelessWidget {
const XiaoConnectorView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocBuilder<XiaoConnectorCubit, XiaoConnectorState>(
builder: (context, state) {
return switch (state.status) {
XiaoConnectorStatus.initial => ElevatedButton(
onPressed: () {
context.read<XiaoConnectorCubit>().connect();
},
child: const Text('Connect'),
),
XiaoConnectorStatus.loading => const CircularProgressIndicator(),
XiaoConnectorStatus.connected => Column(
children: [
ElevatedButton(
onPressed: () {
context.read<XiaoConnectorCubit>().startCapturing(
captureType: 'test',
);
},
child: const Text('Start Capturing'),
),
ElevatedButton(
onPressed: () {
context.read<XiaoConnectorCubit>().readFromObjectBox();
},
child: const Text('Get Points'),
),
],
),
XiaoConnectorStatus.capturing => const CaptureView(),
XiaoConnectorStatus.failure => const FailureView(),
};
},
),
);
}
}

View File

@ -0,0 +1,22 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@RoutePage()
class XiaoDataPage extends StatelessWidget {
const XiaoDataPage({super.key});
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
class XiaoDataView extends StatelessWidget {
const XiaoDataView({super.key});
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}

View File

@ -0,0 +1 @@
export 'view/view.dart';

View File

@ -6,9 +6,11 @@ import FlutterMacOS
import Foundation
import flutter_blue_plus
import objectbox_flutter_libs
import path_provider_foundation
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterBluePlusPlugin.register(with: registry.registrar(forPlugin: "FlutterBluePlusPlugin"))
ObjectboxFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "ObjectboxFlutterLibsPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
}

View File

@ -2,6 +2,10 @@ PODS:
- flutter_blue_plus (0.0.1):
- FlutterMacOS
- FlutterMacOS (1.0.0)
- ObjectBox (4.0.1)
- objectbox_flutter_libs (0.0.1):
- FlutterMacOS
- ObjectBox (= 4.0.1)
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
@ -9,21 +13,30 @@ PODS:
DEPENDENCIES:
- flutter_blue_plus (from `Flutter/ephemeral/.symlinks/plugins/flutter_blue_plus/macos`)
- FlutterMacOS (from `Flutter/ephemeral`)
- objectbox_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/objectbox_flutter_libs/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
SPEC REPOS:
trunk:
- ObjectBox
EXTERNAL SOURCES:
flutter_blue_plus:
:path: Flutter/ephemeral/.symlinks/plugins/flutter_blue_plus/macos
FlutterMacOS:
:path: Flutter/ephemeral
objectbox_flutter_libs:
:path: Flutter/ephemeral/.symlinks/plugins/objectbox_flutter_libs/macos
path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
SPEC CHECKSUMS:
flutter_blue_plus: e2868679021f19d12a8c0c58a33f1df66ec7fa6a
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
ObjectBox: 0bc4bb75eea85f6af06b369148b334c2056bbc29
objectbox_flutter_libs: 769e6f44f7381c8a8e46a2ed5c71c6068bb476f7
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367
COCOAPODS: 1.13.0
COCOAPODS: 1.16.2

View File

@ -228,7 +228,6 @@
523E0585C8B64B20217F29E1 /* Pods-RunnerTests.profile-development.xcconfig */,
378BBA354E8F3A05134CE72F /* Pods-RunnerTests.profile-staging.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
@ -282,6 +281,7 @@
33CC10E52044A3C60003C045 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
@ -500,7 +500,9 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.RunnerTests";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -515,7 +517,9 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.RunnerTests";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -530,7 +534,9 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.RunnerTests";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -567,9 +573,11 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -594,12 +602,14 @@
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
FLAVOR_APP_NAME = "Xiao Pet Tracker";
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_NAME = "$(FLAVOR_APP_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
@ -610,6 +620,8 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Manual;
DEAD_CODE_STRIPPING = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = "Profile-production";
@ -642,9 +654,11 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@ -695,9 +709,11 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -722,12 +738,14 @@
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
FLAVOR_APP_NAME = "Xiao Pet Tracker";
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_NAME = "$(FLAVOR_APP_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -744,12 +762,14 @@
CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
FLAVOR_APP_NAME = "Xiao Pet Tracker";
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_NAME = "$(FLAVOR_APP_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 5.0;
@ -760,6 +780,8 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Manual;
DEAD_CODE_STRIPPING = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = "Debug-production";
@ -768,6 +790,8 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEAD_CODE_STRIPPING = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = "Release-production";
@ -800,9 +824,11 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@ -834,12 +860,14 @@
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
FLAVOR_APP_NAME = "[STG] Xiao Pet Tracker";
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.stg";
PRODUCT_NAME = "$(FLAVOR_APP_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -854,7 +882,9 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.RunnerTests";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -867,6 +897,8 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Manual;
DEAD_CODE_STRIPPING = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = "Debug-staging";
@ -899,9 +931,11 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@ -933,12 +967,14 @@
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
FLAVOR_APP_NAME = "[DEV] Xiao Pet Tracker";
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.dev";
PRODUCT_NAME = "$(FLAVOR_APP_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -953,7 +989,9 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.RunnerTests";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -966,6 +1004,8 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Manual;
DEAD_CODE_STRIPPING = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = "Debug-development";
@ -998,9 +1038,11 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -1025,12 +1067,14 @@
CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
FLAVOR_APP_NAME = "[DEV] Xiao Pet Tracker";
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.dev";
PRODUCT_NAME = "$(FLAVOR_APP_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1044,7 +1088,9 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.RunnerTests";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -1057,6 +1103,8 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEAD_CODE_STRIPPING = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = "Release-development";
@ -1089,9 +1137,11 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -1116,12 +1166,14 @@
CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
FLAVOR_APP_NAME = "[STG] Xiao Pet Tracker";
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.stg";
PRODUCT_NAME = "$(FLAVOR_APP_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1135,7 +1187,9 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.RunnerTests";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -1148,6 +1202,8 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEAD_CODE_STRIPPING = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = "Release-staging";
@ -1180,9 +1236,11 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -1207,12 +1265,14 @@
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
FLAVOR_APP_NAME = "[DEV] Xiao Pet Tracker";
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.dev";
PRODUCT_NAME = "$(FLAVOR_APP_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1226,7 +1286,9 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.RunnerTests";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -1239,6 +1301,8 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Manual;
DEAD_CODE_STRIPPING = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = "Profile-development";
@ -1271,9 +1335,11 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -1298,12 +1364,14 @@
CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEAD_CODE_STRIPPING = YES;
FLAVOR_APP_NAME = "[STG] Xiao Pet Tracker";
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.stg";
PRODUCT_NAME = "$(FLAVOR_APP_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1317,7 +1385,9 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.example.verygoodcore.xiao-pet-tracker.RunnerTests";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -1330,6 +1400,8 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Manual;
DEAD_CODE_STRIPPING = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = "Profile-staging";

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
LastUpgradeVersion = "1610"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
LastUpgradeVersion = "1610"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
LastUpgradeVersion = "1610"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -10,5 +10,7 @@
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.app-sandbox</key>
<false/>
</dict>
</plist>

View File

@ -4,5 +4,7 @@
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.app-sandbox</key>
<false/>
</dict>
</plist>

View File

@ -38,6 +38,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.11.0"
auto_route:
dependency: "direct main"
description:
name: auto_route
sha256: b83e8ce46da7228cdd019b5a11205454847f0a971bca59a7529b98df9876889b
url: "https://pub.dev"
source: hosted
version: "9.2.2"
auto_route_generator:
dependency: "direct dev"
description:
name: auto_route_generator
sha256: c9086eb07271e51b44071ad5cff34e889f3156710b964a308c2ab590769e79e6
url: "https://pub.dev"
source: hosted
version: "9.0.0"
beacon_distance:
dependency: "direct main"
description:
name: beacon_distance
sha256: "59ea80f7d31c7e9591e2095dae808d15a7fb28243da276019190ea94d1203cf7"
url: "https://pub.dev"
source: hosted
version: "0.0.3"
bloc:
dependency: "direct main"
description:
@ -62,6 +86,70 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.1"
build:
dependency: transitive
description:
name: build
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
build_config:
dependency: transitive
description:
name: build_config
sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
url: "https://pub.dev"
source: hosted
version: "1.1.1"
build_daemon:
dependency: transitive
description:
name: build_daemon
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a"
url: "https://pub.dev"
source: hosted
version: "2.4.2"
build_runner:
dependency: "direct dev"
description:
name: build_runner
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
url: "https://pub.dev"
source: hosted
version: "2.4.13"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0
url: "https://pub.dev"
source: hosted
version: "7.3.2"
built_collection:
dependency: transitive
description:
name: built_collection
sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
url: "https://pub.dev"
source: hosted
version: "5.1.1"
built_value:
dependency: transitive
description:
name: built_value
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
url: "https://pub.dev"
source: hosted
version: "8.9.2"
characters:
dependency: transitive
description:
@ -70,6 +158,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
url: "https://pub.dev"
source: hosted
version: "2.0.3"
clock:
dependency: transitive
description:
@ -78,6 +174,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.1"
code_builder:
dependency: transitive
description:
name: code_builder
sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e"
url: "https://pub.dev"
source: hosted
version: "4.10.1"
collection:
dependency: transitive
description:
@ -110,6 +214,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.6"
dart_style:
dependency: transitive
description:
name: dart_style
sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab"
url: "https://pub.dev"
source: hosted
version: "2.3.7"
diff_match_patch:
dependency: transitive
description:
@ -118,6 +230,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.4.1"
ditredi:
dependency: "direct main"
description:
name: ditredi
sha256: "0b6c5334fa4198a3e880d1865eece06189edf91ae894087ba67d347ead5aae4e"
url: "https://pub.dev"
source: hosted
version: "2.0.2"
equatable:
dependency: "direct main"
description:
name: equatable
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
url: "https://pub.dev"
source: hosted
version: "2.0.5"
fake_async:
dependency: transitive
description:
@ -142,19 +270,27 @@ packages:
url: "https://pub.dev"
source: hosted
version: "7.0.1"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
url: "https://pub.dev"
source: hosted
version: "1.1.1"
flat_buffers:
dependency: transitive
description:
name: flat_buffers
sha256: "380bdcba5664a718bfd4ea20a45d39e13684f5318fcd8883066a55e21f37f4c3"
url: "https://pub.dev"
source: hosted
version: "23.5.26"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_animate:
dependency: transitive
description:
name: flutter_animate
sha256: "7c8a6594a9252dad30cc2ef16e33270b6248c4dedc3b3d06c86c4f3f4dc05ae5"
url: "https://pub.dev"
source: hosted
version: "4.5.0"
flutter_bloc:
dependency: "direct main"
description:
@ -184,27 +320,40 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_shaders:
flutter_svg:
dependency: transitive
description:
name: flutter_shaders
sha256: "34794acadd8275d971e02df03afee3dee0f98dbfb8c4837082ad0034f612a3e2"
name: flutter_svg
sha256: "1b7723a814d84fb65869ea7115cdb3ee7c3be5a27a755c1ec60e049f6b9fcbb2"
url: "https://pub.dev"
source: hosted
version: "0.1.3"
flutter_svg_plus:
dependency: transitive
description:
name: flutter_svg_plus
sha256: "4dcfedc6c7dd6e8c6b23cce4034cd78501cf00ea183c68840f0065178a68d86a"
url: "https://pub.dev"
source: hosted
version: "2.0.13+1"
version: "2.0.11"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
forui:
dependency: "direct main"
description:
name: forui
sha256: b3b4652aaf7e6e3f8165a234a05a53cd80e13b805ae78004b8e5ef35dd67e51c
url: "https://pub.dev"
source: hosted
version: "0.6.1"
forui_assets:
dependency: "direct main"
description:
name: forui_assets
sha256: "48a036b329a855db9a18ebb3db98d5e9d1320479d747b48efd4e698ec7b1f178"
url: "https://pub.dev"
source: hosted
version: "0.3.0"
frontend_server_client:
dependency: transitive
description:
@ -213,6 +362,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.0"
get_it:
dependency: "direct main"
description:
name: get_it
sha256: c49895c1ecb0ee2a0ec568d39de882e2c299ba26355aa6744ab1001f98cebd15
url: "https://pub.dev"
source: hosted
version: "8.0.2"
glob:
dependency: transitive
description:
@ -221,6 +378,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.2"
google_fonts:
dependency: transitive
description:
name: google_fonts
sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82
url: "https://pub.dev"
source: hosted
version: "6.2.1"
graphs:
dependency: transitive
description:
name: graphs
sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
http:
dependency: transitive
description:
@ -265,10 +438,18 @@ packages:
dependency: transitive
description:
name: js
sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
version: "0.7.1"
version: "0.6.7"
json_annotation:
dependency: transitive
description:
name: json_annotation
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
url: "https://pub.dev"
source: hosted
version: "4.9.0"
leak_tracker:
dependency: transitive
description:
@ -301,14 +482,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
lucide_icons_flutter:
dependency: transitive
description:
name: lucide_icons_flutter
sha256: c1b4250f23ab64e2db3c456db0633077aed7b2afd0dd4a6d3bb38c88cb3d666c
url: "https://pub.dev"
source: hosted
version: "1.2.1"
macros:
dependency: transitive
description:
@ -365,6 +538,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.0"
nitrogen_flutter_svg:
dependency: transitive
description:
name: nitrogen_flutter_svg
sha256: "2c473caaeeeddb11a437e72f9d112622619493ce22dcd6b41f7364cb999b8e2b"
url: "https://pub.dev"
source: hosted
version: "0.3.0+1"
nitrogen_types:
dependency: transitive
description:
name: nitrogen_types
sha256: "04c3e921fe59a47710b81f6bfd3c4dfeb819ca16e25ad6824dcc5b44ca39ed46"
url: "https://pub.dev"
source: hosted
version: "0.3.0+1"
node_preamble:
dependency: transitive
description:
@ -373,6 +562,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.2"
objectbox:
dependency: "direct main"
description:
name: objectbox
sha256: ea823f4bf1d0a636e7aa50b43daabb64dd0fbd80b85a033016ccc1bc4f76f432
url: "https://pub.dev"
source: hosted
version: "4.0.3"
objectbox_flutter_libs:
dependency: "direct main"
description:
name: objectbox_flutter_libs
sha256: c91350bbbce5e6c2038255760b5be988faead004c814f833c2cd137445c6ae70
url: "https://pub.dev"
source: hosted
version: "4.0.3"
objectbox_generator:
dependency: "direct dev"
description:
name: objectbox_generator
sha256: "96da521f2cef455cd524f8854e31d64495c50711ad5f1e2cf3142a8e527bc75f"
url: "https://pub.dev"
source: hosted
version: "4.0.3"
package_config:
dependency: transitive
description:
@ -382,7 +595,7 @@ packages:
source: hosted
version: "2.1.0"
path:
dependency: transitive
dependency: "direct main"
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
@ -398,13 +611,13 @@ packages:
source: hosted
version: "1.0.1"
path_provider:
dependency: transitive
dependency: "direct main"
description:
name: path_provider
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "2.1.5"
path_provider_android:
dependency: transitive
description:
@ -445,6 +658,54 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.0"
permission_handler:
dependency: "direct main"
description:
name: permission_handler
sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb"
url: "https://pub.dev"
source: hosted
version: "11.3.1"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
sha256: "71bbecfee799e65aff7c744761a57e817e73b738fedf62ab7afd5593da21f9f1"
url: "https://pub.dev"
source: hosted
version: "12.0.13"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
sha256: e6f6d73b12438ef13e648c4ae56bd106ec60d17e90a59c4545db6781229082a0
url: "https://pub.dev"
source: hosted
version: "9.4.5"
permission_handler_html:
dependency: transitive
description:
name: permission_handler_html
sha256: af26edbbb1f2674af65a8f4b56e1a6f526156bc273d0e65dd8075fab51c78851
url: "https://pub.dev"
source: hosted
version: "0.1.3+2"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: e9c8eadee926c4532d0305dff94b85bf961f16759c3af791486613152af4b4f9
url: "https://pub.dev"
source: hosted
version: "4.2.3"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
url: "https://pub.dev"
source: hosted
version: "0.2.1"
petitparser:
dependency: transitive
description:
@ -469,6 +730,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.8"
pointycastle:
dependency: transitive
description:
name: pointycastle
sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe"
url: "https://pub.dev"
source: hosted
version: "3.9.1"
pool:
dependency: transitive
description:
@ -493,14 +762,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
shadcn_ui:
dependency: "direct main"
pubspec_parse:
dependency: transitive
description:
name: shadcn_ui
sha256: "4932db4b88303e517657c7e02af12b034713962ff171ef4402829f98de56b46d"
name: pubspec_parse
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
url: "https://pub.dev"
source: hosted
version: "0.13.5"
version: "1.3.0"
shelf:
dependency: transitive
description:
@ -538,6 +807,14 @@ packages:
description: flutter
source: sdk
version: "0.0.99"
source_gen:
dependency: transitive
description:
name: source_gen
sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832"
url: "https://pub.dev"
source: hosted
version: "1.5.0"
source_map_stack_trace:
dependency: transitive
description:
@ -578,6 +855,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.2"
stream_transform:
dependency: transitive
description:
name: stream_transform
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
stream_with_value:
dependency: transitive
description:
@ -594,6 +879,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
sugar:
dependency: transitive
description:
name: sugar
sha256: "9bfbba7793b5e3650003fca22a857a1d8485e99bf17558cad406a74ba5c4aa3c"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
term_glyph:
dependency: transitive
description:
@ -626,14 +919,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.6.4"
two_dimensional_scrollables:
timing:
dependency: transitive
description:
name: two_dimensional_scrollables
sha256: b6028c80e782e58a5d18f9491737aae4f70d72dc08050ac92006905c7c0b5e21
name: timing
sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
url: "https://pub.dev"
source: hosted
version: "0.3.3"
version: "1.0.1"
typed_data:
dependency: transitive
description:
@ -642,6 +935,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.4.0"
vector_graphics:
dependency: transitive
description:
name: vector_graphics
sha256: "0b9149c6ddb013818075b072b9ddc1b89a5122fff1275d4648d297086b46c4f0"
url: "https://pub.dev"
source: hosted
version: "1.1.12"
vector_graphics_codec:
dependency: transitive
description:
@ -650,22 +951,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.11+1"
vector_graphics_compiler_plus:
vector_graphics_compiler:
dependency: transitive
description:
name: vector_graphics_compiler_plus
sha256: d7dba09b427f65cf7718ae8102e8fbc8ea3b5aabbf4551d070dd2f533581f23f
name: vector_graphics_compiler
sha256: f3b9b6e4591c11394d4be4806c63e72d3a41778547b2c1e2a8a04fadcfd7d173
url: "https://pub.dev"
source: hosted
version: "1.1.12"
vector_graphics_plus:
dependency: transitive
description:
name: vector_graphics_plus
sha256: fbe58ab75d28de33496781a5222224a821e5a4a08f7cd013418f0acc457af50e
url: "https://pub.dev"
source: hosted
version: "1.1.13"
vector_math:
dependency: transitive
description:

View File

@ -7,21 +7,35 @@ environment:
sdk: ^3.5.0
dependencies:
auto_route: ^9.2.2
beacon_distance: ^0.0.3
bloc: ^8.1.4
ditredi: ^2.0.2
equatable: ^2.0.5
flutter:
sdk: flutter
flutter_bloc: ^8.1.6
flutter_blue_plus_windows: ^1.24.15
flutter_localizations:
sdk: flutter
forui: ^0.6.1
forui_assets: ^0.3.0
get_it: ^8.0.2
intl: ^0.19.0
shadcn_ui: ^0.13.5
objectbox: ^4.0.3
objectbox_flutter_libs: any
path: ^1.9.0
path_provider: ^2.1.5
permission_handler: ^11.3.1
dev_dependencies:
auto_route_generator: ^9.0.0
bloc_test: ^9.1.7
build_runner: ^2.4.13
flutter_test:
sdk: flutter
mocktail: ^1.0.4
objectbox_generator: any
very_good_analysis: ^6.0.0
flutter:

View File

@ -0,0 +1,9 @@
{
"go.toolsEnvVars": {
"GOOS": "linux",
"GOARCH": "arm",
"GOROOT": "/Users/fabian/Library/Caches/tinygo/goroot-a02c847ffd7efbf1e1c759b3cf7d01927ed38f0106b48dbfb04faff6caf9ce40",
"GOFLAGS": "-tags=cortexm,baremetal,linux,arm,nrf52840,nrf,softdevice,s140v7,nrf52840_reset_uf2,xiao_ble,tinygo,purego,osusergo,math_big_pure_go,gc.conservative,scheduler.tasks,serial.usb"
},
"go.buildTags": "softdevice",
}

View File

@ -1,17 +1,7 @@
arduino:
tinygo flash -target=arduino
xiao: flash
esp32:
tinygo flash -target=esp32-mini32 -port=/dev/cu.usbserial-1110
prepare:
./flashing_time.py
odroid:
tinygo flash -target=esp32-mini32 -port=/dev/tty.SLAB_USBtoUART
xiao:
flash:
tinygo flash -target=xiao-ble
debug:
tinygo gdb -target=xiao-ble
test:
tinygo build -target=xiao-ble -o test.uf2

View File

@ -0,0 +1,15 @@
#!/usr/bin/env python
from subprocess import run
# requires pySerial:
# python -m pip install pyserial
import serial
# grab the port for the seeed nrf52 (only connect one at a time)
data = run("ls /dev/ | grep 'cu.usbmodem'", capture_output=True, shell=True, text=True)
ser = serial.Serial("/dev/" + data.stdout.strip(), 1200)
# send 16 null characters as reset signal to enter the bootloader
ser.write(b"\x00" * 16)
ser.close()

View File

@ -1,6 +1,7 @@
package main
import (
"encoding/binary"
"fmt"
"machine"
"math/rand"
@ -10,27 +11,32 @@ import (
"tinygo.org/x/drivers/lsm6ds3tr"
)
// TinyGo Drivers Docs:
// https://github.com/tinygo-org/drivers
// TinyGo Bluetooth Docs:
// https://github.com/tinygo-org/bluetooth
var adapter = bluetooth.DefaultAdapter
var ledColor = [3]byte{0xff, 0x00, 0x00}
var ledColor = [3]byte{0x00, 0x00, 0xff}
var leds = [3]machine.Pin{machine.LED_RED, machine.LED_GREEN, machine.LED_BLUE}
var hasColorChange = true
var heartRate uint8 = 75 // 75bpm
var senseAccelerationData string = "-0.000 -0.000 -0.000"
var senseRotationData string = "-0.000 -0.000 -0.000"
var bleConnected bool = false
var (
// a0b40001-926d-4d61-98df-8c5c62ee53b3
serviceUUID = [16]byte{0xa0, 0xb4, 0x00, 0x01, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3}
senseServiceUUID = [16]byte{0xa0, 0xb4, 0x00, 0x03, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3}
charUUID = [16]byte{0xa0, 0xb4, 0x00, 0x02, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3}
senseCharUUID = [16]byte{0xa0, 0xb4, 0x00, 0x04, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3}
LSM6DS3TRService = [16]byte{0x4C, 0x53, 0x4D, 0x36, 0x44, 0x53, 0x33, 0x54, 0x52, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65}
accelerationData = [16]byte{0x61, 0x63, 0x63, 0x65, 0x6C, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x44, 0x61, 0x74, 0x61}
tempSenseService = [16]byte{0x74, 0x65, 0x6D, 0x70, 0x53, 0x65, 0x6E, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65}
temperatureSense = [16]byte{0x74, 0x65, 0x6D, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x6E, 0x73, 0x65}
)
func main() {
println("starting")
// Configure LSM6DS3TR
machine.I2C0.Configure(machine.I2CConfig{})
@ -42,6 +48,10 @@ func main() {
time.Sleep(time.Second)
}
}
//
// for _, led := range leds {
// led.Configure(machine.PinConfig{Mode: machine.PinOutput})
// }
// Configure Bluetooth
must("enable BLE stack", adapter.Enable())
@ -49,6 +59,9 @@ func main() {
must("config adv", adv.Configure(bluetooth.AdvertisementOptions{
LocalName: "Go Bluetooth",
ManufacturerData: []bluetooth.ManufacturerDataElement{
// 0xFFFF: Special Use/Default ID
// Bluetooth Company Identifiers:
// https://gist.github.com/angorb/f92f76108b98bb0d81c74f60671e9c67
{CompanyID: 0xffff, Data: []byte{0x01, 0x02}},
},
}))
@ -56,124 +69,96 @@ func main() {
adapter.SetConnectHandler(func(device bluetooth.Device, connected bool) {
if connected {
println("connected, not advertising...")
// leds[0].Low()
// leds[1].High()
// ledColor[0] = 0
// ledColor[1] = 1
// ledColor[2] = 0
// hasColorChange = true
bleConnected = true
} else {
println("disconnected, advertising...")
// leds[0].High()
// leds[1].Low()
// ledColor[0] = 0
// ledColor[1] = 0
// ledColor[2] = 1
// hasColorChange = true
bleConnected = false
}
})
//
// Start Bluetooth advertisment
must("start adv", adv.Start())
println("advertising...")
// address, _ := adapter.Address()
var ledColorCharacteristic bluetooth.Characteristic
must("add led service", adapter.AddService(&bluetooth.Service{
UUID: bluetooth.NewUUID(serviceUUID),
Characteristics: []bluetooth.CharacteristicConfig{
{
Handle: &ledColorCharacteristic,
UUID: bluetooth.NewUUID(charUUID),
Value: ledColor[:],
Flags: bluetooth.CharacteristicReadPermission | bluetooth.CharacteristicWritePermission | bluetooth.CharacteristicWriteWithoutResponsePermission,
WriteEvent: func(client bluetooth.Connection, offset int, value []byte) {
if offset != 0 || len(value) != 3 {
return
}
ledColor[0] = value[0]
ledColor[1] = value[1]
ledColor[2] = value[2]
hasColorChange = true
},
},
},
}))
var senseCharacteristic bluetooth.Characteristic
must("add sense service", adapter.AddService(&bluetooth.Service{
UUID: bluetooth.NewUUID(senseServiceUUID),
UUID: bluetooth.NewUUID(LSM6DS3TRService),
Characteristics: []bluetooth.CharacteristicConfig{
{
Handle: &senseCharacteristic,
UUID: bluetooth.NewUUID(senseCharUUID),
UUID: bluetooth.NewUUID(accelerationData),
Value: []byte(senseAccelerationData),
Flags: bluetooth.CharacteristicNotifyPermission | bluetooth.CharacteristicReadPermission | bluetooth.CharacteristicWritePermission | bluetooth.CharacteristicWriteWithoutResponsePermission,
},
},
}))
for _, led := range leds {
led.Configure(machine.PinConfig{Mode: machine.PinOutput})
}
// var tempCharacteristic bluetooth.Characteristic
// must("add temperature service", adapter.AddService(&bluetooth.Service{
// UUID: bluetooth.NewUUID(tempSenseService),
// Characteristics: []bluetooth.CharacteristicConfig{
// {
// Handle: &tempCharacteristic,
// UUID: bluetooth.NewUUID(temperatureSense),
// Value: []byte(tempData),
// Flags: bluetooth.CharacteristicNotifyPermission | bluetooth.CharacteristicReadPermission,
// },
// },
// }))
// Loop
//nextBeat := time.Now()
// Main Loop
for {
time.Sleep(500 * time.Millisecond)
//nextBeat = nextBeat.Add(time.Minute / time.Duration(heartRate))
//println("tick", time.Now().Format("04:05.000"))
//time.Sleep(nextBeat.Sub(time.Now()))
time.Sleep(100 * time.Millisecond)
// for !hasColorChange {
// for i, led := range leds {
// led.Set(ledColor[i] == 0)
// }
// time.Sleep(10 * time.Millisecond)
// }
// hasColorChange = false
// for i, led := range leds {
// led.Set(ledColor[i] == 0)
// }
// random variation in heartrate
// heartRate = randomInt(65, 85)
//heartRate = 85
// Only read and update sensor data
// with an active bluetooth connection
if bleConnected {
X, Y, Z, _ := accel.ReadRotation()
rotX := fmt.Sprintf("rX=%f", float32(X)/100000000)
rotY := fmt.Sprintf("rY=%f", float32(Y)/100000000)
rotZ := fmt.Sprintf("rZ=%f", float32(Z)/100000000)
// and push the next notification
x, y, z, _ := accel.ReadAcceleration()
accel := fmt.Sprintf("%.3f,%.3f,%.3f", float32(x)/1000000, float32(y)/1000000, float32(z)/1000000)
//senseAccelerationData = dataTest
x, y, z, _ := accel.ReadAcceleration()
dataTest := fmt.Sprintf("%.3f %.3f %.3f", float32(x)/1000000, float32(y)/1000000, float32(z)/1000000)
senseAccelerationData = dataTest
//tempTest, _ := accel.ReadTemperature()
//tempTestBytes := []byte{}
//tempData = fmt.Sprintf("%i", tempTest)
senseCharacteristic.Write([]byte(senseAccelerationData))
//senseCharacteristic.Write([]byte(dataRotation))
//senseCharacteristic.Write([]byte("-0.0,-1.2,-5.6"))
senseCharacteristic.Write([]byte(rotX))
senseCharacteristic.Write([]byte(rotY))
senseCharacteristic.Write([]byte(rotZ))
senseCharacteristic.Write([]byte(accel))
println(senseAccelerationData)
// bs := make([]byte, 4)
// binary.LittleEndian.PutUint32(bs, X)
//x, _, _, _ := accel.ReadAcceleration()
//heartRate = uint8(x)
//dataTest := fmt.Sprintf("%d, %d, %d", float32(x)/1000000, float32(y)/1000000, float32(z)/1000000)
//dataSense = dataTest
// dataTest := fmt.Sprintf("%d, %d, %d", float32(x)/1000000, float32(y)/1000000, float32(z)/1000000)
//var test = []byte(dataTest)
//senseCharacteristic.Write([]byte(dataSense))
// println("DATA:")
//println(test)
//println("Acceleration:", float32(x)/1000000, float32(y)/1000000, float32(z)/1000000)
//binary.LittleEndian.AppendUint32(tempTestBytes, uint32(tempTest))
//tempCharacteristic.Write(tempTestBytes)
}
}
// for {
// if !accel.Connected() {
// println("LSM6DS3TR not connected")
// time.Sleep(time.Second)
// continue
// }
// x, y, z, _ := accel.ReadAcceleration()
// println("Acceleration:", float32(x)/1000000, float32(y)/1000000, float32(z)/1000000)
// x, y, z, _ = accel.ReadRotation()
// println("Gyroscope:", float32(x)/1000000, float32(y)/1000000, float32(z)/1000000)
// x, _ = accel.ReadTemperature()
// println("Degrees C", float32(x)/1000, "\n\n")
// time.Sleep(time.Millisecond * 100)
// }
// led := machine.LED
// led.Configure(machine.PinConfig{Mode: machine.PinOutput})
// for {
// led.Low()
// time.Sleep(time.Millisecond * 2000)
// println("OFF")
// led.High()
// time.Sleep(time.Millisecond * 2000)
// println("ON")
// }
}
func must(action string, err error) {