mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2026-03-11 07:31:44 +00:00
1
.gitignore
vendored
1
.gitignore
vendored
@ -28,7 +28,6 @@ migrate_working_dir/
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
.pub-cache/
|
||||
.pub/
|
||||
/build/
|
||||
|
||||
# Symbolication related
|
||||
|
||||
@ -9,14 +9,14 @@ PODS:
|
||||
- Firebase/Crashlytics (10.20.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseCrashlytics (~> 10.20.0)
|
||||
- firebase_analytics (10.8.6):
|
||||
- firebase_analytics (10.8.7):
|
||||
- Firebase/Analytics (= 10.20.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- firebase_core (2.25.4):
|
||||
- firebase_core (2.25.5):
|
||||
- Firebase/CoreOnly (= 10.20.0)
|
||||
- Flutter
|
||||
- firebase_crashlytics (3.4.15):
|
||||
- firebase_crashlytics (3.4.16):
|
||||
- Firebase/Crashlytics (= 10.20.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
@ -188,9 +188,9 @@ EXTERNAL SOURCES:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Firebase: 10c8cb12fb7ad2ae0c09ffc86cd9c1ab392a0031
|
||||
firebase_analytics: 9c600045bfb4d16dd78593d18f32c99bb77e5001
|
||||
firebase_core: a46c312d8bae4defa3d009b2aa7b5b413aeb394e
|
||||
firebase_crashlytics: 3054fbdd2b4a4a91f25a15e57c9f1bd2a9ed81ae
|
||||
firebase_analytics: 2c1c3057d5da3bd3aab819f7e6ee153a4e46c59e
|
||||
firebase_core: c8628c7ce80f79439149549052bff22f6784fbf5
|
||||
firebase_crashlytics: 012078b4eec6fc9716f97ba3da0f0e44a04e95b1
|
||||
FirebaseAnalytics: a2731bf3670747ce8f65368b118d18aa8e368246
|
||||
FirebaseCore: 28045c1560a2600d284b9c45a904fe322dc890b6
|
||||
FirebaseCoreExtension: 1c044fd46e95036cccb29134757c499613f3f564
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
import '../../../../generated/assets.dart';
|
||||
@ -30,9 +29,9 @@ class AppBarHomeDropdown extends StatelessWidget {
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
const Gap(5),
|
||||
const SizedBox(width: 5),
|
||||
const BodyLarge(text: 'Home'),
|
||||
const Gap(5),
|
||||
const SizedBox(width: 5),
|
||||
const Icon(
|
||||
Icons.expand_more,
|
||||
color: Colors.black,
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
part 'auth_state.dart';
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
part of 'auth_cubit.dart';
|
||||
|
||||
@immutable
|
||||
abstract class AuthState {}
|
||||
|
||||
class AuthInitial extends AuthState {}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_text_button.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/syncrow_logo.dart';
|
||||
|
||||
@ -26,12 +25,12 @@ class AuthViewBody extends StatelessWidget {
|
||||
Navigator.popAndPushNamed(context, Routes.homeRoute);
|
||||
},
|
||||
),
|
||||
const Gap(15),
|
||||
const SizedBox(height: 15),
|
||||
const DefaultTextButton(
|
||||
text: 'Sign Up',
|
||||
isSecondary: true,
|
||||
),
|
||||
const Gap(20),
|
||||
const SizedBox(height: 20),
|
||||
Center(
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
@ -43,7 +42,7 @@ class AuthViewBody extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
const Gap(30),
|
||||
const SizedBox(height: 30),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/dashboard/view/widgets/carbon_emission.dart';
|
||||
import 'package:syncrow_app/features/dashboard/view/widgets/consumption.dart';
|
||||
import 'package:syncrow_app/features/dashboard/view/widgets/live_monitor_tab.dart';
|
||||
@ -28,7 +27,7 @@ class DashboardView extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const LiveMonitorTab(),
|
||||
const Gap(10),
|
||||
const SizedBox(height: 10),
|
||||
const EnergyUsage(),
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 20),
|
||||
@ -40,7 +39,7 @@ class DashboardView extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Consumption(),
|
||||
Gap(20),
|
||||
SizedBox(height: 20),
|
||||
CarbonEmission(),
|
||||
],
|
||||
),
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/dashboard/view/widgets/card_title.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/united_text.dart';
|
||||
@ -31,7 +30,7 @@ class CarbonEmission extends StatelessWidget {
|
||||
const CardTitle(
|
||||
title: "Carbon Emission",
|
||||
),
|
||||
const Gap(10),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
@ -46,7 +45,7 @@ class CarbonEmission extends StatelessWidget {
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
const Gap(5),
|
||||
const SizedBox(height: 5),
|
||||
const Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@ -64,7 +63,7 @@ class CarbonEmission extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
const Gap(20),
|
||||
const SizedBox(width: 20),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@ -76,7 +75,7 @@ class CarbonEmission extends StatelessWidget {
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
const Gap(5),
|
||||
const SizedBox(width: 5),
|
||||
const Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/dashboard/view/widgets/card_title.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/united_text.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||
@ -44,7 +43,7 @@ class Consumption extends StatelessWidget {
|
||||
valueWeight: FontWeight.normal,
|
||||
unit: "Units",
|
||||
),
|
||||
const Gap(30),
|
||||
const SizedBox(width: 30),
|
||||
UnitedText(
|
||||
value: "${MediaQuery.sizeOf(context).height.ceil()}",
|
||||
valueSize: MediaQuery.sizeOf(context).height.ceil() > 680
|
||||
|
||||
@ -65,13 +65,13 @@ class EnergyUsage extends StatelessWidget {
|
||||
case 0:
|
||||
return SideTitleWidget(
|
||||
axisSide: meta.axisSide,
|
||||
child: BodySmall(text: '1'),
|
||||
child: const BodySmall(text: '1'),
|
||||
);
|
||||
|
||||
case 11:
|
||||
return SideTitleWidget(
|
||||
axisSide: meta.axisSide,
|
||||
child: BodySmall(text: '28'),
|
||||
child: const BodySmall(text: '28'),
|
||||
);
|
||||
default:
|
||||
return Container();
|
||||
@ -172,7 +172,7 @@ class EnergyUsage extends StatelessWidget {
|
||||
|
||||
return SideTitleWidget(
|
||||
axisSide: meta.axisSide,
|
||||
child: BodySmall(text: 'Feb'),
|
||||
child: const BodySmall(text: 'Feb'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
|
||||
@ -37,7 +36,7 @@ class LiveMonitorWidget extends StatelessWidget {
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
const Gap(5),
|
||||
const SizedBox(width: 5),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
||||
52
lib/features/devices/bloc/ac/ac_cubit.dart
Normal file
52
lib/features/devices/bloc/ac/ac_cubit.dart
Normal file
@ -0,0 +1,52 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/model/ac_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
|
||||
part 'ac_state.dart';
|
||||
|
||||
class AcCubit extends Cubit<AcState> {
|
||||
AcCubit() : super(AcInitial());
|
||||
|
||||
static AcCubit get(context) => BlocProvider.of(context);
|
||||
|
||||
void selectAC(ACModel model) {
|
||||
model.isSelected = !model.isSelected;
|
||||
emit(ACSelected());
|
||||
}
|
||||
|
||||
ACModel? getSelectedAC() {
|
||||
for (var ac in DevicesCubit.categories[0].devices) {
|
||||
if (ac is ACModel && ac.isSelected) {
|
||||
return ac;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void setTempToAll(double temperature) {
|
||||
for (DeviceModel ac in DevicesCubit.categories[0].devices) {
|
||||
if (ac is ACModel) {
|
||||
setACTemp(ac, temperature);
|
||||
}
|
||||
}
|
||||
universalACTemp = temperature;
|
||||
emit(ACsTempChanged(temperature));
|
||||
}
|
||||
|
||||
void setACTemp(ACModel model, double temp) {
|
||||
model.temperature = temp;
|
||||
emit(ACsTempChanged(temp));
|
||||
}
|
||||
|
||||
double getTemp(int index) {
|
||||
var device = DevicesCubit.categories[0].devices[index];
|
||||
if (device is ACModel) {
|
||||
return device.temperature;
|
||||
}
|
||||
return 0.0; // or any default value you prefer
|
||||
}
|
||||
|
||||
static double universalACTemp = 20;
|
||||
}
|
||||
@ -1,123 +0,0 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/model/ac_model.dart';
|
||||
|
||||
part 'ac_state.dart';
|
||||
|
||||
class AcCubit extends Cubit<AcState> {
|
||||
AcCubit() : super(AcInitial()) {
|
||||
averageTempForAll();
|
||||
updateACsStatus();
|
||||
}
|
||||
|
||||
static AcCubit get(context) => BlocProvider.of(context);
|
||||
|
||||
void selectAC(ACModel model) {
|
||||
model.isSelected = !model.isSelected;
|
||||
emit(ACSelected());
|
||||
}
|
||||
|
||||
ACModel? getSelectedAC() {
|
||||
for (var ac in DevicesCubit.categories[0].devices) {
|
||||
if (ac.isSelected) {
|
||||
return ac;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void turnACOn(ACModel model) {
|
||||
if (!model.status) {
|
||||
model.status = true;
|
||||
updateACsStatus();
|
||||
emit(ACTurnedOn());
|
||||
}
|
||||
}
|
||||
|
||||
void turnACOff(ACModel model) {
|
||||
if (model.status) {
|
||||
model.status = false;
|
||||
updateACsStatus();
|
||||
emit(ACTurnedOff());
|
||||
}
|
||||
}
|
||||
|
||||
void updateACsStatus() {
|
||||
bool tempStatus = DevicesCubit.categories[0].devices[0].status;
|
||||
for (var AC in DevicesCubit.categories[0].devices) {
|
||||
//check if there any AC have a different status than the initial ==> turn off the universal switch
|
||||
if (AC.status != tempStatus) {
|
||||
DevicesCubit.categories[0].devicesStatus = false;
|
||||
emit(ACsStatusChanged());
|
||||
return;
|
||||
}
|
||||
DevicesCubit.categories[0].devicesStatus = tempStatus;
|
||||
emit(ACsStatusChanged());
|
||||
}
|
||||
}
|
||||
|
||||
void turnAllACsOff() {
|
||||
for (var ac in DevicesCubit.categories[0].devices) {
|
||||
ac.status = false;
|
||||
}
|
||||
updateACsStatus();
|
||||
emit(SwitchACsOff());
|
||||
}
|
||||
|
||||
void turnAllACsOn() {
|
||||
for (var ac in DevicesCubit.categories[0].devices) {
|
||||
ac.status = true;
|
||||
}
|
||||
updateACsStatus();
|
||||
emit(SwitchACsOn());
|
||||
}
|
||||
|
||||
void setTempToAll(double temperature) {
|
||||
for (var ac in DevicesCubit.categories[0].devices) {
|
||||
ac.temperature = temperature;
|
||||
}
|
||||
averageTempForAll();
|
||||
emit(ACsTempChanged(temperature));
|
||||
}
|
||||
|
||||
void increaseACTemp(int index) {
|
||||
DevicesCubit.categories[0].devices[index].temperature += .5;
|
||||
averageTempForAll();
|
||||
emit(ACsTempChanged(DevicesCubit.categories[0].devices[index].temperature));
|
||||
}
|
||||
|
||||
void decreaseACTemp(int index) {
|
||||
DevicesCubit.categories[0].devices[index].temperature -= .5;
|
||||
averageTempForAll();
|
||||
emit(ACsTempChanged(DevicesCubit.categories[0].devices[index].temperature));
|
||||
}
|
||||
|
||||
void setACTemp(ACModel model, double temp) {
|
||||
model.temperature = temp;
|
||||
averageTempForAll();
|
||||
emit(ACsTempChanged(temp));
|
||||
}
|
||||
|
||||
double getTemp(int index) {
|
||||
return DevicesCubit.categories[0].devices[index].temperature;
|
||||
}
|
||||
|
||||
static double averageTemp = 0;
|
||||
|
||||
void averageTempForAll() {
|
||||
double tempSum = 0;
|
||||
for (var ac in DevicesCubit.categories[0].devices) {
|
||||
tempSum += ac.temperature;
|
||||
}
|
||||
|
||||
averageTemp = tempSum / DevicesCubit.categories[0].devices.length;
|
||||
|
||||
averageTemp = (averageTemp * 2).round() / 2;
|
||||
|
||||
emit(ACsAverageTemp());
|
||||
}
|
||||
|
||||
/// implement the fan speed and temp mode change
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/model/ac_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/light_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/gateway/gateway_view.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/screens/screens_view.dart';
|
||||
@ -14,21 +16,11 @@ import '../view/widgets/lights/lights_view.dart';
|
||||
part 'devices_state.dart';
|
||||
|
||||
class DevicesCubit extends Cubit<DevicesState> {
|
||||
DevicesCubit() : super(DevicesInitial()) {
|
||||
// getCategories();
|
||||
}
|
||||
|
||||
void changeCategorySwitchValue(DevicesCategoryModel category) {
|
||||
category.devicesStatus = !category.devicesStatus;
|
||||
for (var device in category.devices) {
|
||||
device.status = category.devicesStatus;
|
||||
}
|
||||
emit(CategorySwitchChanged());
|
||||
}
|
||||
DevicesCubit() : super(DevicesInitial());
|
||||
|
||||
static DevicesCubit get(context) => BlocProvider.of(context);
|
||||
|
||||
static var categories = <DevicesCategoryModel>[
|
||||
static List<DevicesCategoryModel> categories = [
|
||||
DevicesCategoryModel(
|
||||
devices: [
|
||||
ACModel(
|
||||
@ -38,6 +30,11 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
temperature: 20,
|
||||
fanSpeed: 0,
|
||||
tempMode: 0,
|
||||
coolTo: 20,
|
||||
type: '',
|
||||
location: '',
|
||||
image: '',
|
||||
timer: null,
|
||||
),
|
||||
ACModel(
|
||||
name: "Master Bedroom AC",
|
||||
@ -46,6 +43,37 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
temperature: 20,
|
||||
fanSpeed: 0,
|
||||
tempMode: 0,
|
||||
coolTo: 20,
|
||||
type: '',
|
||||
location: '',
|
||||
image: '',
|
||||
timer: null,
|
||||
),
|
||||
ACModel(
|
||||
name: "Kitchen AC",
|
||||
id: '2',
|
||||
status: false,
|
||||
temperature: 20,
|
||||
fanSpeed: 0,
|
||||
tempMode: 0,
|
||||
coolTo: 20,
|
||||
type: '',
|
||||
location: '',
|
||||
image: '',
|
||||
timer: null,
|
||||
),
|
||||
ACModel(
|
||||
name: "Bathroom AC",
|
||||
id: '3',
|
||||
status: false,
|
||||
temperature: 20,
|
||||
fanSpeed: 0,
|
||||
tempMode: 0,
|
||||
coolTo: 20,
|
||||
type: '',
|
||||
location: '',
|
||||
image: '',
|
||||
timer: null,
|
||||
),
|
||||
],
|
||||
icon: Assets.iconsAC,
|
||||
@ -54,7 +82,68 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
page: const ACsView(),
|
||||
),
|
||||
DevicesCategoryModel(
|
||||
devices: [],
|
||||
devices: [
|
||||
LightModel(
|
||||
name: "Living Room Light",
|
||||
id: '0',
|
||||
status: false,
|
||||
color: 0,
|
||||
brightness: 20,
|
||||
lightingMode: 1,
|
||||
timer: null,
|
||||
type: '',
|
||||
location: '',
|
||||
image: '',
|
||||
),
|
||||
LightModel(
|
||||
name: "Master Bedroom Light",
|
||||
id: '1',
|
||||
status: false,
|
||||
color: 2,
|
||||
brightness: 40,
|
||||
lightingMode: 1,
|
||||
timer: null,
|
||||
type: '',
|
||||
location: '',
|
||||
image: '',
|
||||
),
|
||||
LightModel(
|
||||
name: "Kitchen Light",
|
||||
id: '2',
|
||||
status: false,
|
||||
color: 1,
|
||||
brightness: 60,
|
||||
lightingMode: 1,
|
||||
timer: null,
|
||||
type: '',
|
||||
location: '',
|
||||
image: '',
|
||||
),
|
||||
LightModel(
|
||||
name: "Bathroom Light",
|
||||
id: '3',
|
||||
status: false,
|
||||
color: 3,
|
||||
brightness: 80,
|
||||
lightingMode: 1,
|
||||
timer: null,
|
||||
type: '',
|
||||
location: '',
|
||||
image: '',
|
||||
),
|
||||
LightModel(
|
||||
name: "Balcony Light",
|
||||
id: '4',
|
||||
status: false,
|
||||
color: 4,
|
||||
brightness: 100,
|
||||
lightingMode: 1,
|
||||
timer: null,
|
||||
type: '',
|
||||
location: '',
|
||||
image: '',
|
||||
),
|
||||
],
|
||||
icon: Assets.iconsLight,
|
||||
name: 'Lights',
|
||||
type: DeviceType.Lights,
|
||||
@ -99,9 +188,63 @@ class DevicesCubit extends Cubit<DevicesState> {
|
||||
return null;
|
||||
}
|
||||
|
||||
void changeCategorySwitchValue(DevicesCategoryModel category) {
|
||||
if (category.devicesStatus != null) {
|
||||
category.devicesStatus = !category.devicesStatus!;
|
||||
for (var device in category.devices) {
|
||||
device.status = category.devicesStatus;
|
||||
}
|
||||
} else {
|
||||
category.devicesStatus = true;
|
||||
for (var device in category.devices) {
|
||||
device.status = true;
|
||||
}
|
||||
}
|
||||
|
||||
emit(CategorySwitchChanged());
|
||||
}
|
||||
|
||||
void turnOnOffDevice(DeviceModel device) {
|
||||
device.status = !device.status!;
|
||||
DevicesCategoryModel category =
|
||||
categories.firstWhere((category) => category.devices.contains(device));
|
||||
updateDevicesStatus(category);
|
||||
emit(DeviceSwitchChanged());
|
||||
}
|
||||
|
||||
void updateDevicesStatus(DevicesCategoryModel category) {
|
||||
bool? tempStatus = category.devices[0].status;
|
||||
for (var ac in category.devices) {
|
||||
//check if there any ac have a different status than the initial ==> turn off the universal switch
|
||||
if (ac.status != tempStatus) {
|
||||
category.devicesStatus = null;
|
||||
emit(DeviceSwitchChanged());
|
||||
return;
|
||||
}
|
||||
category.devicesStatus = tempStatus;
|
||||
emit(DeviceSwitchChanged());
|
||||
}
|
||||
}
|
||||
|
||||
void turnAllDevicesOff(DevicesCategoryModel category) {
|
||||
for (var device in category.devices) {
|
||||
device.status = false;
|
||||
}
|
||||
updateDevicesStatus(category);
|
||||
emit(CategorySwitchChanged());
|
||||
}
|
||||
|
||||
void turnAllDevicesOn(DevicesCategoryModel category) {
|
||||
for (var device in category.devices) {
|
||||
device.status = true;
|
||||
}
|
||||
updateDevicesStatus(category);
|
||||
emit(CategorySwitchChanged());
|
||||
}
|
||||
|
||||
void areAllDevicesOff(DevicesCategoryModel category) {
|
||||
for (var device in category.devices) {
|
||||
if (device.status) {
|
||||
if (device.status ?? false) {
|
||||
category.devicesStatus = false;
|
||||
emit(CategorySwitchChanged());
|
||||
return;
|
||||
|
||||
@ -17,8 +17,4 @@ class DevicesCategoryChanged extends DevicesState {}
|
||||
|
||||
class CategorySwitchChanged extends DevicesState {}
|
||||
|
||||
class SwitchACsOff extends DevicesState {}
|
||||
|
||||
class SwitchACsOn extends DevicesState {}
|
||||
|
||||
class SetACsTemp extends DevicesState {}
|
||||
class DeviceSwitchChanged extends DevicesState {}
|
||||
|
||||
32
lib/features/devices/bloc/lights/lights_cubit.dart
Normal file
32
lib/features/devices/bloc/lights/lights_cubit.dart
Normal file
@ -0,0 +1,32 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/model/light_model.dart';
|
||||
|
||||
part 'lights_state.dart';
|
||||
|
||||
class LightsCubit extends Cubit<LightsState> {
|
||||
LightsCubit() : super(LightsInitial());
|
||||
|
||||
static LightsCubit get(context) => BlocProvider.of(context);
|
||||
|
||||
int getBrightness(LightModel light) {
|
||||
return light.brightness.toInt();
|
||||
}
|
||||
|
||||
setBrightness(LightModel light, double value) {
|
||||
value = (value / 5).ceil() * 5;
|
||||
if (value != light.brightness) {
|
||||
light.brightness = value;
|
||||
emit(LightBrightnessChanged(value));
|
||||
}
|
||||
}
|
||||
|
||||
onHorizontalDragUpdate(LightModel light, double dx, double screenWidth) {
|
||||
double newBrightness = (dx / (screenWidth - 15) * 100);
|
||||
if (newBrightness > 100) {
|
||||
newBrightness = 100;
|
||||
} else if (newBrightness < 0) {
|
||||
newBrightness = 0;
|
||||
}
|
||||
setBrightness(light, newBrightness);
|
||||
}
|
||||
}
|
||||
21
lib/features/devices/bloc/lights/lights_state.dart
Normal file
21
lib/features/devices/bloc/lights/lights_state.dart
Normal file
@ -0,0 +1,21 @@
|
||||
part of 'lights_cubit.dart';
|
||||
|
||||
abstract class LightsState {}
|
||||
|
||||
class LightsInitial extends LightsState {}
|
||||
|
||||
class LightsLoading extends LightsState {}
|
||||
|
||||
class LightsSuccess extends LightsState {}
|
||||
|
||||
class LightsFailure extends LightsState {
|
||||
final String message;
|
||||
|
||||
LightsFailure(this.message);
|
||||
}
|
||||
|
||||
class LightBrightnessChanged extends LightsState {
|
||||
final double brightness;
|
||||
|
||||
LightBrightnessChanged(this.brightness);
|
||||
}
|
||||
@ -1,21 +1,56 @@
|
||||
class ACModel {
|
||||
final String name;
|
||||
final String id;
|
||||
late bool status;
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
|
||||
class ACModel extends DeviceModel {
|
||||
late double temperature;
|
||||
|
||||
late int fanSpeed;
|
||||
|
||||
late int tempMode;
|
||||
|
||||
bool isSelected = false;
|
||||
late double coolTo;
|
||||
|
||||
ACModel({
|
||||
required this.name,
|
||||
required this.id,
|
||||
required this.status,
|
||||
required this.temperature,
|
||||
required this.fanSpeed,
|
||||
required this.tempMode,
|
||||
required this.coolTo,
|
||||
required super.id,
|
||||
required super.name,
|
||||
required super.type,
|
||||
required super.status,
|
||||
required super.location,
|
||||
required super.image,
|
||||
required super.timer,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'temperature': temperature,
|
||||
'fanSpeed': fanSpeed,
|
||||
'tempMode': tempMode,
|
||||
'coolTo': coolTo,
|
||||
'id': id,
|
||||
'name': name,
|
||||
'status': status,
|
||||
'type': type,
|
||||
'location': location,
|
||||
'image': image,
|
||||
};
|
||||
}
|
||||
|
||||
factory ACModel.fromJson(Map<String, dynamic> json) {
|
||||
return ACModel(
|
||||
id: json['id'],
|
||||
name: json['name'],
|
||||
status: json['status'],
|
||||
temperature: json['temperature'],
|
||||
fanSpeed: json['fanSpeed'],
|
||||
tempMode: json['tempMode'],
|
||||
type: json['type'],
|
||||
location: json['location'],
|
||||
image: json['image'],
|
||||
timer: json['timer'],
|
||||
coolTo: json['coolTo'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
// ignore_for_file: constant_identifier_names
|
||||
|
||||
import 'ac_model.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
|
||||
class DevicesCategoryModel {
|
||||
final String name;
|
||||
@ -8,8 +9,8 @@ class DevicesCategoryModel {
|
||||
|
||||
final Widget page;
|
||||
|
||||
bool devicesStatus = false;
|
||||
final List<ACModel> devices;
|
||||
bool? devicesStatus = false;
|
||||
final List<DeviceModel> devices;
|
||||
|
||||
final DeviceType type;
|
||||
bool isSelected;
|
||||
@ -23,7 +24,7 @@ class DevicesCategoryModel {
|
||||
required this.devices}) {
|
||||
//sets the initial status of the devices
|
||||
if (devices.isNotEmpty) {
|
||||
bool tempStatus = devices.first.status;
|
||||
bool tempStatus = devices.first.status ?? false;
|
||||
for (var device in devices) {
|
||||
if (device.status != tempStatus) {
|
||||
devicesStatus = false;
|
||||
|
||||
20
lib/features/devices/model/device_model.dart
Normal file
20
lib/features/devices/model/device_model.dart
Normal file
@ -0,0 +1,20 @@
|
||||
abstract class DeviceModel {
|
||||
final String? id;
|
||||
final String? name;
|
||||
final String? type;
|
||||
bool? status;
|
||||
final String? location;
|
||||
final String? image;
|
||||
final double? timer;
|
||||
bool isSelected = false;
|
||||
|
||||
DeviceModel({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.type,
|
||||
required this.status,
|
||||
required this.location,
|
||||
required this.image,
|
||||
required this.timer,
|
||||
});
|
||||
}
|
||||
51
lib/features/devices/model/light_model.dart
Normal file
51
lib/features/devices/model/light_model.dart
Normal file
@ -0,0 +1,51 @@
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
|
||||
class LightModel extends DeviceModel {
|
||||
late double brightness;
|
||||
late int color;
|
||||
|
||||
late int lightingMode;
|
||||
|
||||
LightModel({
|
||||
required this.brightness,
|
||||
required this.color,
|
||||
required this.lightingMode,
|
||||
required super.id,
|
||||
required super.name,
|
||||
required super.type,
|
||||
required super.status,
|
||||
required super.location,
|
||||
required super.image,
|
||||
required super.timer,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'luminance': brightness,
|
||||
'color': color,
|
||||
'lightingMode': lightingMode,
|
||||
'timer': timer,
|
||||
'id': id,
|
||||
'name': name,
|
||||
'status': status,
|
||||
'type': type,
|
||||
'location': location,
|
||||
'image': image,
|
||||
};
|
||||
}
|
||||
|
||||
factory LightModel.fromJson(Map<String, dynamic> json) {
|
||||
return LightModel(
|
||||
id: json['id'],
|
||||
name: json['name'],
|
||||
status: json['status'],
|
||||
brightness: json['luminance'],
|
||||
color: json['color'],
|
||||
lightingMode: json['lightingMode'],
|
||||
timer: json['timer'],
|
||||
type: json['type'],
|
||||
location: json['location'],
|
||||
image: json['image'],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/devices/model/ac_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface_controls.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface_temp_unit.dart';
|
||||
@ -17,7 +16,7 @@ class AcInterface extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const Gap(20),
|
||||
const SizedBox(height: 20),
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxHeight: 400,
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/devices/model/ac_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_mode_control_unit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
@ -17,42 +16,39 @@ class AcInterfaceControls extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Expanded(
|
||||
flex: 3,
|
||||
child: Column(
|
||||
children: [
|
||||
const Gap(10),
|
||||
ACModeControlUnit(model: acModel),
|
||||
Gap(10),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: DefaultContainer(
|
||||
height: 55,
|
||||
child: Center(
|
||||
child: SvgPicture.asset(Assets.iconsAutomatedClock),
|
||||
),
|
||||
return Column(
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
ACModeControlUnit(model: acModel),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: DefaultContainer(
|
||||
height: 55,
|
||||
child: Center(
|
||||
child: SvgPicture.asset(Assets.iconsAutomatedClock),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Gap(10),
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: DefaultContainer(
|
||||
height: 55,
|
||||
child: Center(
|
||||
child: SvgPicture.asset(Assets.iconsLock),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: DefaultContainer(
|
||||
height: 55,
|
||||
child: Center(
|
||||
child: SvgPicture.asset(Assets.iconsLock),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:sleek_circular_slider/sleek_circular_slider.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/AC/ac_cubit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
@ -23,6 +23,7 @@ class AcInterfaceTempUnit extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
//TODO: use the coolTo value from the model
|
||||
double coolTo = acModel.temperature;
|
||||
return BlocBuilder<AcCubit, AcState>(
|
||||
builder: (context, state) {
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/devices/model/ac_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
|
||||
@ -53,7 +52,7 @@ class _ACModeControlUnitState extends State<ACModeControlUnit> {
|
||||
),
|
||||
),
|
||||
),
|
||||
const Gap(10),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/AC/ac_cubit.dart';import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
import '../../../../../generated/assets.dart';
|
||||
import '../../../model/ac_model.dart';
|
||||
|
||||
class ACTempWidget extends StatelessWidget {
|
||||
const ACTempWidget(
|
||||
this.index, {
|
||||
this.acModel, {
|
||||
super.key,
|
||||
});
|
||||
|
||||
final int index;
|
||||
final ACModel acModel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -30,7 +30,8 @@ class ACTempWidget extends StatelessWidget {
|
||||
dimension: 24,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
AcCubit.get(context).decreaseACTemp(index);
|
||||
AcCubit.get(context)
|
||||
.setACTemp(acModel, acModel.temperature - 0.5);
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
Assets.iconsMinus,
|
||||
@ -38,7 +39,7 @@ class ACTempWidget extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
BodyLarge(
|
||||
text: "${AcCubit.get(context).getTemp(index)}° C",
|
||||
text: "${acModel.temperature}° C",
|
||||
style: context.bodyLarge.copyWith(
|
||||
color: ColorsManager.primaryColor.withOpacity(0.6),
|
||||
fontSize: 23,
|
||||
@ -48,7 +49,8 @@ class ACTempWidget extends StatelessWidget {
|
||||
dimension: 24,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
AcCubit.get(context).increaseACTemp(index);
|
||||
AcCubit.get(context)
|
||||
.setACTemp(acModel, acModel.temperature + 0.5);
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
Assets.iconsPlus,
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/AC/ac_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_mode_control_unit.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_temp_widget.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/universal_ac_switch.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/universal_ac_temp.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/universal_switch.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/devices_default_switch.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
|
||||
import '../../../model/ac_model.dart';
|
||||
|
||||
class ACsList extends StatelessWidget {
|
||||
const ACsList({
|
||||
super.key,
|
||||
@ -16,26 +18,30 @@ class ACsList extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
DevicesCategoryModel category = DevicesCubit.categories[0];
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// universal AC controller
|
||||
const Gap(10),
|
||||
const SizedBox(height: 10),
|
||||
const BodySmall(text: "All ACs"),
|
||||
const Gap(5),
|
||||
const UniversalACSwitch(),
|
||||
const Gap(10),
|
||||
const SizedBox(height: 5),
|
||||
UniversalSwitch(
|
||||
category: category,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
const UniversalACTemp(),
|
||||
const Gap(10),
|
||||
const SizedBox(height: 10),
|
||||
|
||||
// other ACs controls
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.all(0),
|
||||
itemCount: DevicesCubit.categories[0].devices.length,
|
||||
itemCount: category.devices.length,
|
||||
itemBuilder: (context, index) {
|
||||
ACModel ac = category.devices[index] as ACModel;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -43,12 +49,13 @@ class ACsList extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
BodySmall(
|
||||
text: DevicesCubit.categories[0].devices[index].name),
|
||||
BodySmall(text: category.devices[index].name ?? ""),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
AcCubit.get(context).selectAC(
|
||||
DevicesCubit.categories[0].devices[index]);
|
||||
var device = category.devices[index];
|
||||
if (device is ACModel) {
|
||||
AcCubit.get(context).selectAC(device);
|
||||
}
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
@ -63,19 +70,21 @@ class ACsList extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
const Gap(5),
|
||||
DevicesDefaultSwitch(
|
||||
model: DevicesCubit.categories[0].devices[index],
|
||||
),
|
||||
const Gap(10),
|
||||
const SizedBox(height: 5),
|
||||
if (category.devices[index] is ACModel)
|
||||
DevicesDefaultSwitch(
|
||||
model: ac,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
ACTempWidget(
|
||||
index,
|
||||
ac,
|
||||
),
|
||||
const Gap(10),
|
||||
ACModeControlUnit(
|
||||
model: DevicesCubit.categories[0].devices[index],
|
||||
),
|
||||
const Gap(10),
|
||||
const SizedBox(height: 10),
|
||||
if (category.devices[index] is ACModel)
|
||||
ACModeControlUnit(
|
||||
model: ac,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
||||
@ -3,7 +3,7 @@ import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/app_layout/view/widgets/default_app_bar.dart';
|
||||
import 'package:syncrow_app/features/app_layout/view/widgets/default_nav_bar.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/AC/ac_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/model/ac_model.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_list.dart';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/AC/ac_cubit.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
|
||||
import '../../../../../generated/assets.dart';
|
||||
@ -27,7 +27,8 @@ class UniversalACTemp extends StatelessWidget {
|
||||
dimension: 24,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
AcCubit.get(context).setTempToAll(AcCubit.averageTemp + .5);
|
||||
AcCubit.get(context)
|
||||
.setTempToAll(AcCubit.universalACTemp - .5);
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
Assets.iconsMinus,
|
||||
@ -35,7 +36,7 @@ class UniversalACTemp extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
BodyLarge(
|
||||
text: "${AcCubit.averageTemp}° C",
|
||||
text: "${AcCubit.universalACTemp}° C",
|
||||
style: context.bodyLarge.copyWith(
|
||||
color: ColorsManager.primaryColor.withOpacity(0.6),
|
||||
fontSize: 23,
|
||||
@ -45,7 +46,8 @@ class UniversalACTemp extends StatelessWidget {
|
||||
dimension: 24,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
AcCubit.get(context).setTempToAll(AcCubit.averageTemp + .5);
|
||||
AcCubit.get(context)
|
||||
.setTempToAll(AcCubit.universalACTemp + .5);
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
Assets.iconsPlus,
|
||||
|
||||
@ -4,14 +4,14 @@ import 'package:syncrow_app/features/devices/view/widgets/switches.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||
|
||||
class CategoriesView extends StatelessWidget {
|
||||
const CategoriesView({
|
||||
class DevicesCategoriesView extends StatelessWidget {
|
||||
const DevicesCategoriesView({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Column(
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
@ -1,6 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||
@ -34,7 +33,7 @@ class DevicesModeTab extends StatelessWidget {
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
const Gap(5),
|
||||
const SizedBox(width: 5),
|
||||
const BodySmall(
|
||||
text: StringsManager.winter,
|
||||
fontWeight: FontWeight.bold,
|
||||
@ -62,7 +61,7 @@ class DevicesModeTab extends StatelessWidget {
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
const Gap(5),
|
||||
const SizedBox(width: 5),
|
||||
const BodySmall(
|
||||
text: StringsManager.summer,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/categories_view.dart';
|
||||
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/devices_categories_view.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
|
||||
|
||||
import '../../../../utils/resource_manager/strings_manager.dart';
|
||||
import '../../bloc/devices_cubit.dart';
|
||||
import 'switches.dart';
|
||||
|
||||
class DevicesViewBody extends StatelessWidget {
|
||||
const DevicesViewBody({
|
||||
@ -15,9 +19,101 @@ class DevicesViewBody extends StatelessWidget {
|
||||
create: (context) => DevicesCubit(),
|
||||
child: BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) {
|
||||
PageController pageController = PageController();
|
||||
return state is DevicesLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: const CategoriesView();
|
||||
: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height - 252,
|
||||
child: PageView(
|
||||
controller: pageController,
|
||||
children: const [
|
||||
DevicesCategoriesView(),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TitleMedium(
|
||||
text: "Home",
|
||||
style: TextStyle(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
TitleMedium(
|
||||
text: StringsManager.wizard,
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
),
|
||||
),
|
||||
Switches(),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TitleMedium(
|
||||
text: "Office",
|
||||
style: TextStyle(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
TitleMedium(
|
||||
text: StringsManager.wizard,
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
),
|
||||
),
|
||||
Switches(),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SmoothPageIndicator(
|
||||
controller: pageController,
|
||||
count: 3,
|
||||
effect: const WormEffect()),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/lights/lights_cubit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
import '../../../model/light_model.dart';
|
||||
|
||||
class LightBrightness extends StatelessWidget {
|
||||
const LightBrightness({
|
||||
super.key,
|
||||
required this.light,
|
||||
});
|
||||
|
||||
final LightModel light;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<LightsCubit, LightsState>(
|
||||
builder: (context, state) {
|
||||
return GestureDetector(
|
||||
onHorizontalDragUpdate: (details) => LightsCubit.get(context)
|
||||
.onHorizontalDragUpdate(light, details.localPosition.dx,
|
||||
MediaQuery.of(context).size.width - 15),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
const DefaultContainer(
|
||||
height: 60,
|
||||
child: SizedBox.expand(),
|
||||
),
|
||||
AnimatedPositioned(
|
||||
left: 0,
|
||||
duration: const Duration(milliseconds: 50),
|
||||
child: Container(
|
||||
height: 60,
|
||||
width: (MediaQuery.of(context).size.width - 30) *
|
||||
light.brightness /
|
||||
100,
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.primaryColor.withOpacity(0.6),
|
||||
borderRadius: light.brightness != 100
|
||||
? const BorderRadius.only(
|
||||
topLeft: Radius.circular(20),
|
||||
bottomLeft: Radius.circular(20),
|
||||
)
|
||||
: BorderRadius.circular(20),
|
||||
),
|
||||
),
|
||||
),
|
||||
BodyLarge(
|
||||
text: "${light.brightness}%",
|
||||
style: context.bodyLarge.copyWith(
|
||||
color: Colors.black,
|
||||
fontSize: 23,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
58
lib/features/devices/view/widgets/lights/lights_list.dart
Normal file
58
lib/features/devices/view/widgets/lights/lights_list.dart
Normal file
@ -0,0 +1,58 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/lights/light_brightness.dart';
|
||||
|
||||
import '../../../../shared_widgets/devices_default_switch.dart';
|
||||
import '../../../../shared_widgets/text_widgets/body_small.dart';
|
||||
import '../../../model/light_model.dart';
|
||||
|
||||
class LightsList extends StatelessWidget {
|
||||
const LightsList({
|
||||
super.key,
|
||||
required this.lights,
|
||||
});
|
||||
|
||||
final List<LightModel> lights;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.all(0),
|
||||
itemCount: lights.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
BodySmall(text: lights[index].name ?? ""),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
// LightsCubit.get(context).selectAC(device);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
),
|
||||
style: ButtonStyle(
|
||||
padding: MaterialStateProperty.all(
|
||||
const EdgeInsets.all(0),
|
||||
),
|
||||
iconSize: MaterialStateProperty.all(15),
|
||||
alignment: Alignment.bottomRight,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
DevicesDefaultSwitch(model: lights[index]),
|
||||
const SizedBox(height: 10),
|
||||
LightBrightness(light: lights[index]),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,81 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/view/widgets/lights/lights_list.dart';
|
||||
|
||||
import '../../../../../generated/assets.dart';
|
||||
import '../../../../../utils/resource_manager/color_manager.dart';
|
||||
import '../../../../app_layout/view/widgets/default_app_bar.dart';
|
||||
import '../../../../app_layout/view/widgets/default_nav_bar.dart';
|
||||
import '../../../../shared_widgets/text_widgets/body_small.dart';
|
||||
import '../../../bloc/devices_cubit.dart';
|
||||
import '../../../bloc/lights/lights_cubit.dart';
|
||||
import '../../../model/light_model.dart';
|
||||
import '../universal_switch.dart';
|
||||
|
||||
class LightsView extends StatelessWidget {
|
||||
const LightsView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder();
|
||||
return BlocProvider(
|
||||
create: (context) => LightsCubit(),
|
||||
child: BlocBuilder<LightsCubit, LightsState>(
|
||||
builder: (context, state) {
|
||||
List<LightModel> lights = [];
|
||||
for (var device in DevicesCubit.categories[1].devices) {
|
||||
if (device is LightModel) {
|
||||
lights.add(device);
|
||||
}
|
||||
}
|
||||
return AnnotatedRegion(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
backgroundColor: ColorsManager.backgroundColor,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
appBar: const DefaultAppBar(),
|
||||
body: Container(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
height: MediaQuery.sizeOf(context).height,
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(
|
||||
Assets.imagesBackground,
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
opacity: 0.4,
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 70, right: 15, left: 15, bottom: 80),
|
||||
child: SizedBox.expand(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const BodySmall(text: "All Lights"),
|
||||
UniversalSwitch(
|
||||
category: DevicesCubit.categories[1],
|
||||
),
|
||||
LightsList(lights: lights),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: const DefaultNavBar(),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_text_button.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
|
||||
@ -20,7 +19,7 @@ class NoDevicesView extends StatelessWidget {
|
||||
scale: 1,
|
||||
width: 140,
|
||||
),
|
||||
const Gap(15),
|
||||
const SizedBox(height: 15),
|
||||
const Text(
|
||||
'No Devices',
|
||||
style: TextStyle(
|
||||
@ -28,7 +27,7 @@ class NoDevicesView extends StatelessWidget {
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
const Gap(15),
|
||||
const SizedBox(height: 15),
|
||||
const DefaultTextButton(
|
||||
text: 'Add Device',
|
||||
),
|
||||
|
||||
@ -5,6 +5,7 @@ import 'package:syncrow_app/features/shared_widgets/custom_switch.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
|
||||
import 'package:syncrow_app/utils/context_extension.dart';
|
||||
import 'package:syncrow_app/utils/helpers/custom_page_route.dart';
|
||||
|
||||
import '../../bloc/devices_cubit.dart';
|
||||
|
||||
@ -32,7 +33,9 @@ class Switches extends StatelessWidget {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
DevicesCubit.get(context).selectCategory(index);
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) {
|
||||
//Navigate to the chosen category view without animation
|
||||
|
||||
Navigator.push(context, CustomPageRoute(builder: (context) {
|
||||
return DevicesCubit.get(context).chosenCategoryView!;
|
||||
}));
|
||||
},
|
||||
|
||||
@ -1,33 +1,39 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_category_model.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
|
||||
|
||||
import '../../../../../utils/resource_manager/color_manager.dart';
|
||||
import '../../../../shared_widgets/text_widgets/body_medium.dart';
|
||||
import '../../../bloc/ac_cubit.dart';
|
||||
import '../../../../utils/resource_manager/color_manager.dart';
|
||||
import '../../../shared_widgets/text_widgets/body_medium.dart';
|
||||
|
||||
class UniversalACSwitch extends StatelessWidget {
|
||||
const UniversalACSwitch({
|
||||
class UniversalSwitch extends StatelessWidget {
|
||||
const UniversalSwitch({
|
||||
super.key,
|
||||
required this.category,
|
||||
});
|
||||
|
||||
final DevicesCategoryModel category;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
//TODO: Move these to String Manager "ON" and "OFF"
|
||||
return BlocBuilder<AcCubit, AcState>(
|
||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) {
|
||||
bool? status = category.devicesStatus;
|
||||
return Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
AcCubit.get(context).turnAllACsOn();
|
||||
DevicesCubit.get(context).turnAllDevicesOn(category);
|
||||
},
|
||||
child: Container(
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: DevicesCubit.categories[0].devicesStatus
|
||||
? ColorsManager.primaryColor
|
||||
color: status != null
|
||||
? status
|
||||
? ColorsManager.primaryColor
|
||||
: Colors.white
|
||||
: Colors.white,
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(15),
|
||||
@ -36,9 +42,11 @@ class UniversalACSwitch extends StatelessWidget {
|
||||
),
|
||||
child: Center(
|
||||
child: BodyMedium(
|
||||
text: "ON",
|
||||
fontColor: DevicesCubit.categories[0].devicesStatus
|
||||
? Colors.white
|
||||
text: StringsManager.on,
|
||||
fontColor: status != null
|
||||
? status
|
||||
? Colors.white
|
||||
: null
|
||||
: null,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@ -49,14 +57,16 @@ class UniversalACSwitch extends StatelessWidget {
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
AcCubit.get(context).turnAllACsOff();
|
||||
DevicesCubit.get(context).turnAllDevicesOff(category);
|
||||
},
|
||||
child: Container(
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: DevicesCubit.categories[0].devicesStatus
|
||||
? Colors.white
|
||||
: ColorsManager.primaryColor,
|
||||
color: status != null
|
||||
? status
|
||||
? Colors.white
|
||||
: ColorsManager.primaryColor
|
||||
: Colors.white,
|
||||
borderRadius: const BorderRadius.only(
|
||||
topRight: Radius.circular(15),
|
||||
bottomRight: Radius.circular(15),
|
||||
@ -64,10 +74,12 @@ class UniversalACSwitch extends StatelessWidget {
|
||||
),
|
||||
child: Center(
|
||||
child: BodyMedium(
|
||||
text: "OFF",
|
||||
fontColor: DevicesCubit.categories[0].devicesStatus
|
||||
? null
|
||||
: Colors.white,
|
||||
text: StringsManager.off,
|
||||
fontColor: status != null
|
||||
? status
|
||||
? null
|
||||
: Colors.white
|
||||
: null,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
@ -1,5 +1,4 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
part 'layout_state.dart';
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
part of 'layout_cubit.dart';
|
||||
|
||||
@immutable
|
||||
abstract class LayoutState {}
|
||||
|
||||
class LayoutInitial extends LayoutState {}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/menu/model/menu_list_model.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/menu_list_divider.dart';
|
||||
import 'package:syncrow_app/features/menu/view/widgets/menu_list_item.dart';
|
||||
@ -19,11 +18,11 @@ class MenuList extends StatelessWidget {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const Gap(5),
|
||||
const SizedBox(height: 5),
|
||||
BodySmall(
|
||||
text: listModel.label!,
|
||||
),
|
||||
const Gap(5),
|
||||
const SizedBox(height: 5),
|
||||
DefaultContainer(
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
@ -37,7 +36,7 @@ class MenuList extends StatelessWidget {
|
||||
},
|
||||
separatorBuilder: (context, index) => const MenuListDivider()),
|
||||
),
|
||||
const Gap(5),
|
||||
const SizedBox(height: 5),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
|
||||
@ -20,7 +19,7 @@ class ProfileTab extends StatelessWidget {
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Gap(20),
|
||||
SizedBox(height: 20),
|
||||
DefaultContainer(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
part 'profile_state.dart';
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
part of 'profile_cubit.dart';
|
||||
|
||||
@immutable
|
||||
abstract class ProfileState {}
|
||||
|
||||
class ProfileInitial extends ProfileState {}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:syncrow_app/features/scene/model/scene_model.dart';
|
||||
|
||||
part 'scene_state.dart';
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
part of 'scene_cubit.dart';
|
||||
|
||||
@immutable
|
||||
abstract class SceneState {}
|
||||
|
||||
class SceneInitial extends SceneState {}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/scene/bloc/scene_cubit.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
@ -29,7 +28,7 @@ class SceneView extends StatelessWidget {
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const Gap(20),
|
||||
const SizedBox(height: 20),
|
||||
const BodySmall(
|
||||
text: StringsManager.tapToRunRoutine,
|
||||
),
|
||||
@ -71,7 +70,7 @@ class SceneView extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
const Gap(10),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/default_text_button.dart';
|
||||
import 'package:syncrow_app/generated/assets.dart';
|
||||
|
||||
@ -22,13 +21,13 @@ class SceneViewNoScenes extends StatelessWidget {
|
||||
opacity: const AlwaysStoppedAnimation(.5),
|
||||
width: 140,
|
||||
),
|
||||
const Gap(15),
|
||||
const SizedBox(height: 15),
|
||||
const Text(
|
||||
'Home automation saves your time and effort by automating routine tasks.',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: Colors.grey),
|
||||
),
|
||||
const Gap(20),
|
||||
const SizedBox(height: 20),
|
||||
const DefaultTextButton(
|
||||
text: 'Create Scene',
|
||||
)
|
||||
|
||||
@ -22,8 +22,10 @@ class CustomSwitch extends StatelessWidget {
|
||||
height: 28.0,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
color: category.devicesStatus
|
||||
? ColorsManager.primaryColor
|
||||
color: category.devicesStatus != null
|
||||
? category.devicesStatus!
|
||||
? ColorsManager.primaryColor
|
||||
: const Color(0xFFD9D9D9)
|
||||
: const Color(0xFFD9D9D9),
|
||||
),
|
||||
child: Center(
|
||||
@ -37,16 +39,20 @@ class CustomSwitch extends StatelessWidget {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(2.0),
|
||||
child: Container(
|
||||
alignment: category.devicesStatus
|
||||
? Alignment.centerRight
|
||||
alignment: category.devicesStatus != null
|
||||
? category.devicesStatus!
|
||||
? Alignment.centerRight
|
||||
: Alignment.centerLeft
|
||||
: Alignment.centerLeft,
|
||||
child: Container(
|
||||
width: 20.0,
|
||||
height: 20.0,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: category.devicesStatus
|
||||
? ColorsManager.primaryColor
|
||||
color: category.devicesStatus != null
|
||||
? category.devicesStatus!
|
||||
? ColorsManager.primaryColor
|
||||
: Colors.grey
|
||||
: Colors.grey,
|
||||
),
|
||||
),
|
||||
|
||||
@ -6,19 +6,22 @@ class DefaultContainer extends StatelessWidget {
|
||||
required this.child,
|
||||
this.height,
|
||||
this.width,
|
||||
this.color,
|
||||
});
|
||||
|
||||
final double? height;
|
||||
final double? width;
|
||||
final Widget child;
|
||||
|
||||
final Color? color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: height,
|
||||
width: width,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: color ?? Colors.white,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
padding: const EdgeInsets.all(10),
|
||||
|
||||
@ -1,33 +1,34 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart';
|
||||
import 'package:syncrow_app/features/devices/model/ac_model.dart';
|
||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
|
||||
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
|
||||
|
||||
import '../devices/bloc/devices_cubit.dart';
|
||||
|
||||
class DevicesDefaultSwitch extends StatelessWidget {
|
||||
const DevicesDefaultSwitch({
|
||||
super.key,
|
||||
required this.model,
|
||||
});
|
||||
|
||||
final ACModel model;
|
||||
final DeviceModel model;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<AcCubit, AcState>(
|
||||
return BlocBuilder<DevicesCubit, DevicesState>(
|
||||
builder: (context, state) {
|
||||
return Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
AcCubit.get(context).turnACOn(model);
|
||||
DevicesCubit.get(context).turnOnOffDevice(model);
|
||||
},
|
||||
child: Container(
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: model.status
|
||||
color: model.status ?? false
|
||||
? ColorsManager.primaryColor
|
||||
: Colors.white,
|
||||
borderRadius: const BorderRadius.only(
|
||||
@ -38,7 +39,7 @@ class DevicesDefaultSwitch extends StatelessWidget {
|
||||
child: Center(
|
||||
child: BodyMedium(
|
||||
text: "ON",
|
||||
fontColor: model.status ? Colors.white : null,
|
||||
fontColor: model.status ?? false ? Colors.white : null,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
@ -48,12 +49,12 @@ class DevicesDefaultSwitch extends StatelessWidget {
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
AcCubit.get(context).turnACOff(model);
|
||||
DevicesCubit.get(context).turnOnOffDevice(model);
|
||||
},
|
||||
child: Container(
|
||||
height: 60,
|
||||
decoration: BoxDecoration(
|
||||
color: model.status
|
||||
color: model.status ?? false
|
||||
? Colors.white
|
||||
: ColorsManager.primaryColor,
|
||||
borderRadius: const BorderRadius.only(
|
||||
@ -64,7 +65,7 @@ class DevicesDefaultSwitch extends StatelessWidget {
|
||||
child: Center(
|
||||
child: BodyMedium(
|
||||
text: "OFF",
|
||||
fontColor: model.status ? null : Colors.white,
|
||||
fontColor: model.status ?? false ? null : Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
|
||||
11
lib/utils/helpers/custom_page_route.dart
Normal file
11
lib/utils/helpers/custom_page_route.dart
Normal file
@ -0,0 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CustomPageRoute extends MaterialPageRoute {
|
||||
CustomPageRoute({
|
||||
required super.builder,
|
||||
super.settings,
|
||||
});
|
||||
|
||||
@override
|
||||
Duration get transitionDuration => const Duration(milliseconds: 0);
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
// ignore_for_file: lines_longer_than_80_chars, constant_identifier_names
|
||||
|
||||
class StringsManager {
|
||||
static const noRouteFound = 'No route found';
|
||||
@ -22,4 +22,6 @@ class StringsManager {
|
||||
static const winterMode = 'Winter Mode';
|
||||
static const summer = 'Summer';
|
||||
static const summerMode = 'Summer Mode';
|
||||
static const on = 'ON';
|
||||
static const off = 'OFF';
|
||||
}
|
||||
|
||||
68
pubspec.lock
68
pubspec.lock
@ -5,10 +5,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _flutterfire_internals
|
||||
sha256: "737321f9be522620ed3794937298fb0027a48a402624fa2500f7532f94aea810"
|
||||
sha256: fe4c077084ddda88f327dc1c96d16631cd68d4948644593fcbcd911c2c89e2fa
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.22"
|
||||
version: "1.3.23"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -149,34 +149,34 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_analytics
|
||||
sha256: "54681f6a8c35ec782c86680919953edbae66517a718fe7606a7ba52cfa1b36ca"
|
||||
sha256: c6220b23397f9302a42617227ee8fb1c5d718097a5351fcce53561d73fc10339
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.8.6"
|
||||
version: "10.8.7"
|
||||
firebase_analytics_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_analytics_platform_interface
|
||||
sha256: cf7378f407c26fd1f1cc808c0d791f2a15dd4f1fe0626bb2ce6a96663c4d8470
|
||||
sha256: "7f1c02cdd93a5e0a561af2f551465ffb6abdd541dbd0c8a9b8628d9ae0a5d024"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.9.6"
|
||||
version: "3.9.7"
|
||||
firebase_analytics_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_analytics_web
|
||||
sha256: f62c7a2514771f6e122c5b55227c0c7fdaa253cc2fe6efce768897c0fb68a5ab
|
||||
sha256: ebb857c23f35fed52220b6c3271c12eeb6137de3930845223e3d0590b6fd0649
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.5+18"
|
||||
version: "0.5.5+19"
|
||||
firebase_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_core
|
||||
sha256: "7e049e32a9d347616edb39542cf92cd53fdb4a99fb6af0a0bff327c14cd76445"
|
||||
sha256: "797379ea206eaeeb62499775de812761493d0692890fdc7f90b6183a3369176d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.25.4"
|
||||
version: "2.25.5"
|
||||
firebase_core_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -189,26 +189,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_web
|
||||
sha256: "57e61d6010e253b36d38191cefd6199d7849152cdcd234b61ca290cdb278a0ba"
|
||||
sha256: c8e1d59385eee98de63c92f961d2a7062c5d9a65e7f45bdc7f1b0b205aab2492
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.11.4"
|
||||
version: "2.11.5"
|
||||
firebase_crashlytics:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_crashlytics
|
||||
sha256: "4c754db28a7daabe03c4cbf1079dbe81e6f0681284fed6d07e0e640b7f1027c4"
|
||||
sha256: "0126fa101b74fb981796b3e6f47ccf7fc40237ec918327aaec7c0a06fd1bb4c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.15"
|
||||
version: "3.4.16"
|
||||
firebase_crashlytics_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_crashlytics_platform_interface
|
||||
sha256: "08c5d7b5f93dbad7306d26702935abd8b579313ea256eb27006562a1867df249"
|
||||
sha256: cdfa0a20d66e1b32de542883c0ddf651ee9b66b12cebf73067e4d2cdc0865d17
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.6.22"
|
||||
version: "3.6.23"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -335,10 +335,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_svg
|
||||
sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c
|
||||
sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.9"
|
||||
version: "2.0.10+1"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
@ -349,14 +349,6 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
gap:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: gap
|
||||
sha256: f19387d4e32f849394758b91377f9153a1b41d79513ef7668c088c77dbc6955d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
get_it:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -642,6 +634,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
smooth_page_indicator:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: smooth_page_indicator
|
||||
sha256: "725bc638d5e79df0c84658e1291449996943f93bacbc2cec49963dbbab48d8ae"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -734,10 +734,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: url_launcher
|
||||
sha256: c512655380d241a337521703af62d2c122bf7b77a46ff7dd750092aa9433499c
|
||||
sha256: "0ecc004c62fd3ed36a2ffcbe0dd9700aee63bd7532d0b642a488b1ec310f492e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.4"
|
||||
version: "6.2.5"
|
||||
url_launcher_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -806,26 +806,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics
|
||||
sha256: "4ac59808bbfca6da38c99f415ff2d3a5d7ca0a6b4809c71d9cf30fba5daf9752"
|
||||
sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.10+1"
|
||||
version: "1.1.11+1"
|
||||
vector_graphics_codec:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics_codec
|
||||
sha256: f3247e7ab0ec77dc759263e68394990edc608fb2b480b80db8aa86ed09279e33
|
||||
sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.10+1"
|
||||
version: "1.1.11+1"
|
||||
vector_graphics_compiler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics_compiler
|
||||
sha256: "18489bdd8850de3dd7ca8a34e0c446f719ec63e2bab2e7a8cc66a9028dd76c5a"
|
||||
sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.10+1"
|
||||
version: "1.1.11+1"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
19
pubspec.yaml
19
pubspec.yaml
@ -17,25 +17,25 @@ dependencies:
|
||||
cupertino_icons: ^1.0.6
|
||||
shared_preferences: ^2.2.2
|
||||
flutter_animated_dialog: ^2.0.1
|
||||
gap: ^3.0.1
|
||||
flutter_svg: ^2.0.9
|
||||
sleek_circular_slider: ^2.0.1
|
||||
|
||||
flutter_svg: ^2.0.10+1
|
||||
fl_chart: ^0.66.2
|
||||
sleek_circular_slider: ^2.0.1
|
||||
|
||||
# Utility Packages
|
||||
flutter_secure_storage: ^9.0.0
|
||||
cached_network_image: ^3.3.1
|
||||
flutter_dotenv: ^5.1.0
|
||||
intl: ^0.18.1
|
||||
# noinspection YAMLSchemaValidation
|
||||
intl: ^0.18.0
|
||||
get_it: ^7.6.7
|
||||
url_launcher: ^6.2.4
|
||||
url_launcher: ^6.2.5
|
||||
dio: ^5.4.1
|
||||
flutter_localization: ^0.2.0
|
||||
flutter_bloc: ^8.1.4
|
||||
firebase_core: ^2.25.4
|
||||
firebase_analytics: ^10.8.6
|
||||
firebase_crashlytics: ^3.4.15
|
||||
firebase_core: ^2.25.5
|
||||
firebase_analytics: ^10.8.7
|
||||
firebase_crashlytics: ^3.4.16
|
||||
smooth_page_indicator: ^1.1.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
@ -49,7 +49,6 @@ flutter:
|
||||
- assets/images/
|
||||
- assets/icons/
|
||||
- assets/fonts/
|
||||
- assets/
|
||||
fonts:
|
||||
- family: Aftika
|
||||
fonts:
|
||||
|
||||
Reference in New Issue
Block a user