Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into home
Browse files Browse the repository at this point in the history
  • Loading branch information
BryanGazali committed Oct 13, 2021
2 parents b1ad6ee + 7858e4d commit ef1044a
Show file tree
Hide file tree
Showing 24 changed files with 713 additions and 62 deletions.
12 changes: 8 additions & 4 deletions lib/app/app.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import 'package:flutter/material.dart';
import 'package:treehousesble/app/theme.dart';
import 'package:treehousesble/common/constants/env.dart';
import 'package:treehousesble/common/constants/strings.dart';
import 'package:treehousesble/common/navigation/nav.dart';
import 'package:treehousesble/common/route/route_generator.dart';
import 'package:treehousesble/common/route/routes.dart';
import 'package:treehousesble/common/utils/multi_repo_listing.dart';
import 'package:treehousesble/common/widget/global_error_widget.dart';


class App extends StatefulWidget {
App({Key? key}) : super(key: key);
final Env env;

App({Key? key, required this.env}) : super(key: key);

@override
_AppState createState() => _AppState();
Expand All @@ -18,7 +20,9 @@ class App extends StatefulWidget {
class _AppState extends State<App> {
@override
Widget build(BuildContext context) {
return MaterialApp(
return MultiRepoListing(
env: widget.env,
child: MaterialApp(
navigatorKey: Nav.navKey,
builder: (context, Widget? widget) {
setErrorBuilder(context);
Expand All @@ -30,6 +34,6 @@ class _AppState extends State<App> {
title: Strings.APP_TITLE,
initialRoute: Routes.root,
onGenerateRoute: RouteGenerator.generateRoute,
);
));
}
}
134 changes: 134 additions & 0 deletions lib/common/bloc/bluetooth_cubit.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import 'dart:convert';

import 'package:bloc/bloc.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:treehousesble/app/app.dart';
import 'package:treehousesble/common/bloc/bluetooth_state.dart';
import 'package:treehousesble/common/constants/app_constants.dart';
import 'package:treehousesble/common/constants/constant.dart';
import 'package:treehousesble/common/constants/strings.dart';
import 'package:treehousesble/common/shared_pref/shared_pref.dart';

class BluetoothCubit extends Cubit<DataState> {
BluetoothCubit() : super(StateDeviceNotConnected());
final FlutterBlue flutterBlue = FlutterBlue.instance;
final List<BluetoothDevice> devicesList = [];
final Map<Guid, List<int>> readValues = new Map<Guid, List<int>>();
BluetoothCharacteristic? characteristic;

appStart() async {
final bool firstTimeAppOpen = await SharedPref.getFirstTimeAppOpen();
if (firstTimeAppOpen) {
emit(FirstTimeAppOpen());
} else {
emit(NotFirstTimeAppOpen());
}
}
List<int> _sendCommand(String command) {
return utf8.encode(command);
}

writeMessage(String command) async{
if(characteristic != null){
await characteristic?.write(_sendCommand(command), withoutResponse: true);
print("SEND MESSAGE " + command);
readMessage();
}
}

readMessage() async{
if(characteristic != null){
emit(StateReading());
List<int> response = await characteristic!.read();
var responseString = utf8.decode(response);
emit(StateReadSuccess(data: responseString));
}

}

fetchDeviceList(bool filterPi) {
emit(StateLoading());
print("FETCH DEVICE LIST");
flutterBlue.connectedDevices
.asStream()
.listen((List<BluetoothDevice> devices) {
for (BluetoothDevice device in devices) {
_addDeviceTolist(device, filterPi);
}
});
flutterBlue.scanResults.listen((List<ScanResult> results) {
print("Scan result " + results.length.toString());
for (ScanResult result in results) {
_addDeviceTolist(result.device, filterPi);
}
});
flutterBlue.startScan();
}

void _addDeviceTolist(BluetoothDevice device, bool filterPi) {
print("Filter pi " + device.name);
if (!devicesList.contains(device) && checkIfPi(device, filterPi)) {
devicesList.add(device);
}
emit(StateIniital());
emit(StateFoundDevices(list: devicesList));
// if (devicesList.length > 0) );
}

fetchServicesAndConnect(BluetoothDevice device) async {
emit(StateLoading());
try {
await device.connect(timeout: Duration(seconds: 20));
discoverServices(device);
} catch (e) {
if(e.toString().contains("already")){
discoverServices(device);
}else{
emit(StateError(message: "Unable to connect please try again"));
}
}
}

checkDeviceConnected() async {
if (characteristic == null) {
emit(StateDeviceNotConnected());
var connected = await flutterBlue.connectedDevices;
if (connected.length > 0) fetchServicesAndConnect(connected[0]);
} else {
emit(StateDeviceConnected(characteristic: characteristic!));
}
}

bool checkIfPi(BluetoothDevice device, bool filterPi) {
if (filterPi) {
bool isPi = false;
for (int i = 0; i < AppConstants.PI_ADDRESS.length; i++) {
if (device.id
.toString()
.toLowerCase()
.startsWith(AppConstants.PI_ADDRESS[i].toLowerCase())) {
isPi = true;
break;
}
}
return isPi;
}
return true;
}

void discoverServices(BluetoothDevice device)async{
List<BluetoothService> services = await device.discoverServices();
for (BluetoothService service in services) {
if (service.uuid.toString() == Strings.BLUETOOTH_UUID) {
List<BluetoothCharacteristic> characteristics =
service.characteristics;
if (characteristics.length > 0) {
characteristic = characteristics[0];
emit(StateDeviceConnected(characteristic: characteristic!));
print("CONNECTED TO DEVICE");
break;
}
}
}
}
}
79 changes: 79 additions & 0 deletions lib/common/bloc/bluetooth_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_blue/flutter_blue.dart';

class DataState extends Equatable {
final dynamic data;

const DataState({this.data});

@override
List<Object?> get props => [...data];
}

class FirstTimeAppOpen extends DataState {
@override
List<Object> get props => [];
}


class NotFirstTimeAppOpen extends DataState {
@override
List<Object> get props => [];
}


class StateIniital extends DataState {}

class StateLoading extends DataState {}
class StateReading extends DataState {}

class StateError extends DataState {
final String message;

const StateError({required this.message});

@override
List<Object?> get props => [message];
}

class StateNoData extends DataState {
final String message;

const StateNoData({required this.message});

List<Object?> get props => [message];
}

class StateReadSuccess extends DataState {
final dynamic data;

const StateReadSuccess({required this.data}) : super(data: data);

@override
List<Object?> get props => [...data];
}

class StateFoundDevices extends DataState {
final List<BluetoothDevice> list;

const StateFoundDevices({required this.list}) : super(data: list);

@override
List<Object?> get props => [...data];
}


class StateDeviceConnected extends DataState {
final BluetoothCharacteristic characteristic;

const StateDeviceConnected({required this.characteristic});

List<Object?> get props => [];
}

class StateDeviceNotConnected extends DataState {

const StateDeviceNotConnected();

List<Object?> get props => [];
}
22 changes: 22 additions & 0 deletions lib/common/constants/app_constants.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class AppConstants{
static var PI_ADDRESS = [
"B8:27:EB",
"DC:A6:32",
"E4:5F:01",
"B8-27-EB",
"DC-A6-32",
"E4-5F-01",
"B827.EB",
"DCA6.32",
"E45F.01",
"b8:27:eb",
"dc:a6:32",
"e4:5f:01",
"b8-27-eb",
"dc-a6-32",
"e4-5f-01",
"b827.eb",
"dca6.32",
"e45f.01"
];
}
4 changes: 3 additions & 1 deletion lib/common/constants/constant.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export 'assets.dart';

export 'strings.dart';
export 'fonts.dart';
export 'app_constants.dart';
13 changes: 13 additions & 0 deletions lib/common/constants/env.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Env {
Env(this.uuid);
final String uuid;
}

mixin EnvValue {
static final Env development =
Env('6e400001-b5a3-f393-e0a9-e50e24dcca9e');
static final Env staging =
Env('6e400001-b5a3-f393-e0a9-e50e24dcca9e');
static final Env production =
Env('6e400001-b5a3-f393-e0a9-e50e24dcca9e');
}
1 change: 1 addition & 0 deletions lib/common/constants/strings.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
class Strings {
static const BLUETOOTH_UUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
static const APP_TITLE = "Treehouses Remote II";
}
7 changes: 5 additions & 2 deletions lib/common/route/route_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import 'package:flutter/material.dart';
import 'package:treehousesble/common/route/routes.dart';
import 'package:treehousesble/feature/dashboard/screen/dashboard_page.dart';
import 'package:treehousesble/feature/dashboard/screen/dashboard_screen.dart';
import 'package:treehousesble/feature/dashboard/screen/search_screen.dart';
import 'package:treehousesble/feature/dashboard/screen/search_rpi_screen.dart';
import 'package:treehousesble/feature/onboard/ui/screen/landing_page.dart';
import 'package:treehousesble/feature/onboard/ui/screen/onboard_page.dart';
import 'package:treehousesble/feature/onboard/ui/screen/splash_page.dart';

Expand All @@ -13,10 +14,12 @@ class RouteGenerator {
return MaterialPageRoute(builder: (_) => SplashPage());
case Routes.onboarding:
return MaterialPageRoute(builder: (_) => OnboardPage());
case Routes.landing:
return MaterialPageRoute(builder: (_) => LandingPage());
case Routes.dashboard:
return MaterialPageRoute(builder: (_) => DashboardPage());
case Routes.search:
return MaterialPageRoute(builder: (_) => SearchPage());
return MaterialPageRoute(builder: (_) => SearchRpiScreen());
default:
return MaterialPageRoute(builder: (_) => SplashPage());
}
Expand Down
1 change: 1 addition & 0 deletions lib/common/route/routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ class Routes {
static const landing = "/landing";
static const onboarding = "/onboarding";
static const dashboard = "/dashboard";
static const search = "/search";
static const settings = "/settings";
static const notification = "/notification";
static const search = "/search";
Expand Down
4 changes: 4 additions & 0 deletions lib/common/utils/multi_bloc_listing.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:treehousesble/common/bloc/bluetooth_cubit.dart';

class MultiBlocListing extends StatelessWidget {
final Widget child;
Expand All @@ -8,6 +9,9 @@ class MultiBlocListing extends StatelessWidget {
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => BluetoothCubit()..checkDeviceConnected(),
),
],
child: child,
);
Expand Down
10 changes: 8 additions & 2 deletions lib/common/utils/multi_repo_listing.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:treehousesble/common/constants/env.dart';

import 'multi_bloc_listing.dart';

class MultiRepoListing extends StatelessWidget {
final Widget child;
const MultiRepoListing({required this.child});
final Env env;

const MultiRepoListing({required this.child, required this.env});

@override
Widget build(BuildContext context) {
return MultiRepositoryProvider(providers: [], child: MultiBlocListing(child: child));
return MultiRepositoryProvider(providers: [
RepositoryProvider<Env>(create: (context) => env, lazy: true),
], child: MultiBlocListing(child: child));
}
}
2 changes: 1 addition & 1 deletion lib/common/widget/page_wrapper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class _PageWrapperState extends State<PageWrapper> {
@override
Widget build(BuildContext context) {
if (widget.hasScaffold!) {
return Scaffold(body: widget.body);
return Scaffold( body: widget.body);
} else {
return widget.body;
}
Expand Down
Loading

0 comments on commit ef1044a

Please sign in to comment.