AC devices page implemented

AC Cubit Add
New Devices Cubit Arch will be used
Devices Cubit (for devices categories, and devices page)
{
AC cubit,
Lights cubit.
... }
Replaced AssetsManager with Assets Class (auto generated)
This commit is contained in:
Mohammad Salameh
2024-02-26 15:55:22 +03:00
parent c95a9c7817
commit abe7072f2d
72 changed files with 1535 additions and 634 deletions
+8 -8
View File
@@ -3,12 +3,12 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/dashboard/view/dashboard_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/devices_view_body.dart';
import 'package:syncrow_app/features/layout/view/layout_view.dart';
import 'package:syncrow_app/features/menu/view/menu_view.dart';
import 'package:syncrow_app/features/scene/view/scene_view.dart';
import 'package:syncrow_app/utils/resource_manager/assets_manager.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import '../../../generated/assets.dart';
part 'nav_state.dart';
class NavCubit extends Cubit<NavState> {
@@ -27,16 +27,16 @@ class NavCubit extends Cubit<NavState> {
};
var bottomNavItems = [
defaultBottomNavBarItem(icon: IconsManager.dashboard, label: 'Dashboard'),
defaultBottomNavBarItem(icon: IconsManager.layout, label: 'Layout'),
defaultBottomNavBarItem(icon: IconsManager.devices, label: 'Devices'),
defaultBottomNavBarItem(icon: IconsManager.routine, label: 'Routine'),
defaultBottomNavBarItem(icon: IconsManager.menu, label: 'Menu'),
defaultBottomNavBarItem(icon: Assets.iconsDashboard, label: 'Dashboard'),
// defaultBottomNavBarItem(icon: Assets.iconslayout, label: 'Layout'),
defaultBottomNavBarItem(icon: Assets.iconsDevices, label: 'Devices'),
defaultBottomNavBarItem(icon: Assets.iconsRoutines, label: 'Routine'),
defaultBottomNavBarItem(icon: Assets.iconsMenu, label: 'Menu'),
];
final List<Widget> pages = [
const DashboardView(),
const LayoutPage(),
// const LayoutPage(),
const DevicesViewBody(),
const SceneView(),
const MenuView(),
@@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:gap/gap.dart';
import 'package:syncrow_app/utils/resource_manager/assets_manager.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import '../../../../generated/assets.dart';
import '../../../shared_widgets/text_widgets/body_large.dart';
class AppBarHomeDropdown extends StatelessWidget {
@@ -22,7 +22,7 @@ class AppBarHomeDropdown extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SvgPicture.asset(
IconsManager.home,
Assets.iconsHome,
width: 25,
height: 25,
colorFilter: const ColorFilter.mode(
@@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/nav_cubit.dart';
import 'package:syncrow_app/utils/resource_manager/assets_manager.dart';
import '../../../../generated/assets.dart';
class AppBody extends StatelessWidget {
const AppBody({
@@ -18,7 +19,7 @@ class AppBody extends StatelessWidget {
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(
ImageManager.background,
Assets.imagesBackground,
),
fit: BoxFit.cover,
opacity: 0.4,
@@ -35,7 +35,3 @@ class DefaultNavBar extends StatelessWidget {
);
}
}
class DefaultBottomNavBarItem extends BottomNavigationBarItem {
DefaultBottomNavBarItem({required super.icon});
}
@@ -4,7 +4,7 @@ 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';
import 'package:syncrow_app/utils/resource_manager/assets_manager.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
class CarbonEmission extends StatelessWidget {
@@ -38,7 +38,7 @@ class CarbonEmission extends StatelessWidget {
SizedBox.square(
dimension: 30,
child: SvgPicture.asset(
IconsManager.CO2,
Assets.iconsCO2,
fit: BoxFit.contain,
),
),
@@ -68,7 +68,7 @@ class CarbonEmission extends StatelessWidget {
SizedBox.square(
dimension: 30,
child: SvgPicture.asset(
IconsManager.sustainability,
Assets.iconsSustainability,
fit: BoxFit.contain,
),
),
@@ -2,9 +2,10 @@ 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/assets_manager.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
import '../../../../generated/assets.dart';
class Consumption extends StatelessWidget {
const Consumption({
super.key,
@@ -54,7 +55,7 @@ class Consumption extends StatelessWidget {
SizedBox.square(
dimension: 60,
child: Image.asset(
ImageManager.testDash2,
Assets.imagesTestDash2,
fit: BoxFit.contain,
),
)
@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/dashboard/view/widgets/energy_usage_header.dart';
import 'package:syncrow_app/utils/resource_manager/assets_manager.dart';
import 'package:syncrow_app/generated/assets.dart';
class EnergyUsage extends StatelessWidget {
const EnergyUsage({
@@ -23,7 +23,7 @@ class EnergyUsage extends StatelessWidget {
children: [
const EnergyUsageHeader(),
Expanded(
child: Image.asset(ImageManager.testDash),
child: Image.asset(Assets.imagesTestDash),
)
],
),
@@ -1,8 +1,9 @@
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/dashboard/view/widgets/live_monitor_widget.dart';
import 'package:syncrow_app/utils/resource_manager/assets_manager.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
import '../../../../generated/assets.dart';
class LiveMonitorTab extends StatelessWidget {
const LiveMonitorTab({
super.key,
@@ -14,21 +15,21 @@ class LiveMonitorTab extends StatelessWidget {
children: [
Expanded(
child: LiveMonitorWidget(
image: IconsManager.active,
image: Assets.iconsActive,
title: StringsManager.active,
value: '10.00w',
),
),
Expanded(
child: LiveMonitorWidget(
image: IconsManager.voltMeter,
image: Assets.iconsVoltMeter,
title: StringsManager.current,
value: '12.1 A',
),
),
Expanded(
child: LiveMonitorWidget(
image: IconsManager.frequency,
image: Assets.iconsFrequency,
title: StringsManager.frequency,
value: '50 Hz',
),
+57
View File
@@ -0,0 +1,57 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:meta/meta.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
part 'ac_state.dart';
class AcCubit extends Cubit<AcState> {
AcCubit() : super(AcInitial());
static AcCubit get(context) => BlocProvider.of(context);
bool areAllACsOff() {
for (var ac in DevicesCubit.categories[0].devices) {
if (ac.status) {
return false;
}
}
return true;
}
void turnAllACsOff() {
for (var ac in DevicesCubit.categories[0].devices) {
ac.status = false;
}
emit(SwitchACsOff());
}
void turnAllACsOn() {
for (var ac in DevicesCubit.categories[0].devices) {
ac.status = true;
}
emit(SwitchACsOn());
}
void setTempToAll(double temperature) {
for (var ac in DevicesCubit.categories[0].devices) {
ac.temperature = temperature;
}
emit(ACsTempChanged());
}
double averageTempForAll() {
double allTemp = 0;
for (var ac in DevicesCubit.categories[0].devices) {
allTemp += ac.temperature;
}
emit(ACsTempChanged());
double averageTemp = allTemp / DevicesCubit.categories[0].devices.length;
averageTemp = (averageTemp * 2).round() / 2;
return averageTemp;
}
/// implement the fan speed and temp mode change
}
+16
View File
@@ -0,0 +1,16 @@
part of 'ac_cubit.dart';
@immutable
abstract class AcState {}
class AcInitial extends AcState {}
class SwitchACsOff extends AcState {}
class SwitchACsOn extends AcState {}
class ACsTempChanged extends AcState {}
class ACsFanSpeedChanged extends AcState {}
class ACsTempModeChanged extends AcState {}
+110 -79
View File
@@ -1,99 +1,130 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/utils/resource_manager/assets_manager.dart';
import 'package:syncrow_app/features/devices/model/ac_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/curtain_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/door_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/gateway_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/screens_view.dart';
import 'package:syncrow_app/generated/assets.dart';
import '../model/device_category_model.dart';
import '../view/widgets/ac_view.dart';
import '../view/widgets/lights_view.dart';
part 'devices_state.dart';
class DevicesCubit extends Cubit<DevicesState> {
DevicesCubit() : super(DevicesInitial()) {
getCategories();
// getCategories();
}
bool ACSwitchValue = false;
bool lightsSwitchValue = false;
bool doorSwitchValue = false;
bool curtainSwitchValue = false;
bool screensSwitchValue = false;
bool gatewaySwitchValue = false;
/// separate the cubit into different cubits based on devices type
static bool ACSwitchValue = false;
static bool lightsSwitchValue = false;
static bool doorSwitchValue = false;
static bool curtainSwitchValue = false;
static bool screensSwitchValue = false;
static bool gatewaySwitchValue = false;
void changeSwitchValue(DeviceType device) {
switch (device) {
case DeviceType.AC:
ACSwitchValue = !ACSwitchValue;
break;
case DeviceType.Lights:
lightsSwitchValue = !lightsSwitchValue;
break;
case DeviceType.Door:
doorSwitchValue = !doorSwitchValue;
break;
case DeviceType.Curtain:
curtainSwitchValue = !curtainSwitchValue;
break;
case DeviceType.Screens:
screensSwitchValue = !screensSwitchValue;
break;
case DeviceType.Gateway:
gatewaySwitchValue = !gatewaySwitchValue;
break;
}
emit(DevicesSuccess());
void changeCategorySwitchValue(DevicesCategoryModel category) {
category.switchValue = !category.switchValue;
emit(CategorySwitchChanged());
print('${category.name} switch value: ${category.switchValue} ');
}
static DevicesCubit get(context) => BlocProvider.of(context);
var categories = <DevicesCategoryModel>[];
static var categories = <DevicesCategoryModel>[
DevicesCategoryModel(
devices: [
ACModel(
name: "Living Room AC",
id: '0',
status: false,
temperature: 20,
fanSpeed: 0,
tempMode: 0,
),
ACModel(
name: "Master Bedroom AC",
id: '1',
status: false,
temperature: 20,
fanSpeed: 0,
tempMode: 0,
),
],
icon: Assets.iconsAC,
name: 'ACs',
switchValue: ACSwitchValue,
type: DeviceType.AC,
page: const ACView(),
),
DevicesCategoryModel(
devices: [],
icon: Assets.iconsLight,
name: 'Lights',
switchValue: lightsSwitchValue,
type: DeviceType.Lights,
page: const LightsView(),
),
DevicesCategoryModel(
devices: [],
icon: Assets.iconsDoorLock,
name: 'Doors',
switchValue: doorSwitchValue,
type: DeviceType.Door,
page: const DoorView(),
),
DevicesCategoryModel(
devices: [],
icon: Assets.iconsCurtain,
name: 'Curtains',
switchValue: curtainSwitchValue,
type: DeviceType.Curtain,
page: const CurtainView(),
),
DevicesCategoryModel(
devices: [],
icon: Assets.iconsScreen,
name: 'Screens',
switchValue: screensSwitchValue,
type: DeviceType.Screens,
page: const ScreensView(),
),
DevicesCategoryModel(
devices: [],
icon: Assets.iconsGateway,
name: 'Gateway',
switchValue: gatewaySwitchValue,
type: DeviceType.Gateway,
page: const GateWayView(),
),
];
Future<List<DevicesCategoryModel>> getCategories() async {
emit(DevicesLoading());
await Future.delayed(const Duration(seconds: 2));
emit(DevicesSuccess());
Widget? get chosenCategory {
for (var category in categories) {
if (category.isSelected) {
return category.page;
}
}
return null;
}
return categories = [
DevicesCategoryModel(
devices: [],
icon: IconsManager.ac,
name: 'ACs',
switchValue: false,
type: DeviceType.AC,
),
DevicesCategoryModel(
devices: [],
icon: IconsManager.light,
name: 'Lights',
switchValue: false,
type: DeviceType.Lights,
),
DevicesCategoryModel(
devices: [],
icon: IconsManager.doorLock,
name: 'Doors',
switchValue: false,
type: DeviceType.Door,
),
DevicesCategoryModel(
devices: [],
icon: IconsManager.curtain,
name: 'Curtains',
switchValue: false,
type: DeviceType.Curtain,
),
DevicesCategoryModel(
devices: [],
icon: IconsManager.screen,
name: 'Screens',
switchValue: false,
type: DeviceType.Screens,
),
DevicesCategoryModel(
devices: [],
icon: IconsManager.gateway,
name: 'Gateway',
switchValue: false,
type: DeviceType.Gateway,
),
];
void updateCategory(int index) {
for (var i = 0; i < categories.length; i++) {
if (i == index) {
categories[i].isSelected = true;
} else {
categories[i].isSelected = false;
}
}
emit(DevicesCategoryChanged());
}
static void clearCategoriesSelection() {
for (var category in categories) {
category.isSelected = false;
}
}
}
@@ -12,3 +12,13 @@ class DevicesSuccess extends DevicesState {}
class DevicesFailure extends DevicesState {}
class ChangeIndex extends DevicesState {}
class DevicesCategoryChanged extends DevicesState {}
class CategorySwitchChanged extends DevicesState {}
class SwitchACsOff extends DevicesState {}
class SwitchACsOn extends DevicesState {}
class SetACsTemp extends DevicesState {}
+19
View File
@@ -0,0 +1,19 @@
class ACModel {
final String name;
final String id;
late bool status;
late double temperature;
late int fanSpeed;
late int tempMode;
ACModel({
required this.name,
required this.id,
required this.status,
required this.temperature,
required this.fanSpeed,
required this.tempMode,
});
}
@@ -1,16 +1,23 @@
import 'device_model.dart';
import 'package:flutter/cupertino.dart';
import 'ac_model.dart';
class DevicesCategoryModel {
final String name;
final String icon;
final bool switchValue;
final List<DeviceModel> devices;
final Widget page;
bool switchValue;
final List<ACModel> devices;
final DeviceType type;
bool isSelected;
DevicesCategoryModel(
{required this.type,
{this.isSelected = false,
required this.page,
required this.type,
required this.name,
required this.icon,
required this.switchValue,
@@ -1,14 +0,0 @@
class DeviceModel {
final String name;
final String imageUrl;
final String description;
final String category;
final String id;
DeviceModel(
{required this.name,
required this.imageUrl,
required this.description,
required this.category,
required this.id});
}
@@ -0,0 +1,75 @@
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';
import '../../../../generated/assets.dart';
class ACControlUnit extends StatefulWidget {
const ACControlUnit({
super.key,
required this.model,
});
final ACModel model;
@override
State<ACControlUnit> createState() => _ACControlUnitState();
}
class _ACControlUnitState extends State<ACControlUnit> {
var fanSpeeds = [
Assets.iconsFan0,
Assets.iconsFan1,
Assets.iconsFan2,
Assets.iconsFan3,
];
var tempModes = [
Assets.iconsSunnyMode,
Assets.iconsColdMode,
Assets.iconsWindyMode,
];
@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
child: InkWell(
onTap: () {
setState(() {
widget.model.fanSpeed =
widget.model.fanSpeed == 3 ? 0 : widget.model.fanSpeed + 1;
});
},
child: DefaultContainer(
height: 55,
child: Center(
child: SvgPicture.asset(fanSpeeds[widget.model.fanSpeed]),
),
),
),
),
const Gap(10),
Expanded(
child: InkWell(
onTap: () {
setState(() {
widget.model.tempMode =
widget.model.tempMode == 2 ? 0 : widget.model.tempMode + 1;
});
},
child: DefaultContainer(
height: 55,
child: Center(
child: SvgPicture.asset(tempModes[widget.model.tempMode]),
),
),
),
),
],
);
}
}
@@ -0,0 +1,72 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:gap/gap.dart';
import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/view/widgets/a_c_control_unit.dart';
import 'package:syncrow_app/features/devices/view/widgets/devices_temp_widget.dart';
import 'package:syncrow_app/features/devices/view/widgets/universal_a_c_switch.dart';
import 'package:syncrow_app/features/devices/view/widgets/universal_a_c_temp.dart';
import 'package:syncrow_app/features/shared_widgets/devices_default_switch.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
class ACView extends StatelessWidget {
const ACView({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => AcCubit(),
child: BlocBuilder<AcCubit, AcState>(
builder: (context, state) {
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// universal AC controller
const Gap(10),
const BodySmall(text: "All ACs"),
const Gap(5),
const UniversalACSwitch(),
const Gap(10),
const UniversalACTemp(),
const Gap(10),
// other ACs controller
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.all(0),
itemCount: DevicesCubit.categories[0].devices.length,
itemBuilder: (context, index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
BodySmall(
text:
DevicesCubit.categories[0].devices[index].name),
const Gap(5),
DevicesDefaultSwitch(
model: DevicesCubit.categories[0].devices[index],
),
const Gap(10),
DevicesTempWidget(
model: DevicesCubit.categories[0].devices[index],
),
const Gap(10),
ACControlUnit(
model: DevicesCubit.categories[0].devices[index],
),
const Gap(10),
],
);
},
),
],
),
);
},
),
);
}
}
@@ -0,0 +1,10 @@
import 'package:flutter/material.dart';
class CurtainView extends StatelessWidget {
const CurtainView({super.key});
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
@@ -2,7 +2,7 @@ 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/utils/resource_manager/assets_manager.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
class DevicesModeTab extends StatelessWidget {
@@ -30,7 +30,7 @@ class DevicesModeTab extends StatelessWidget {
height: 30,
width: 25,
child: SvgPicture.asset(
IconsManager.winter,
Assets.iconsWinter,
fit: BoxFit.contain,
),
),
@@ -58,7 +58,7 @@ class DevicesModeTab extends StatelessWidget {
height: 30,
width: 25,
child: SvgPicture.asset(
IconsManager.summer,
Assets.iconsSummer,
fit: BoxFit.contain,
),
),
@@ -0,0 +1,74 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/model/ac_model.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';
class DevicesTempWidget extends StatefulWidget {
const DevicesTempWidget({
super.key,
required this.model,
});
final ACModel model;
@override
State<DevicesTempWidget> createState() => _DevicesTempWidgetState();
}
class _DevicesTempWidgetState extends State<DevicesTempWidget> {
// double temp = widget.model.temperature;
@override
Widget build(BuildContext context) {
return DefaultContainer(
height: 60,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
SizedBox.square(
dimension: 24,
child: InkWell(
onTap: () {
setState(() {
// temp = temp - .5;
widget.model.temperature = widget.model.temperature - .5;
});
},
child: SvgPicture.asset(
Assets.iconsMinus,
),
),
),
BodyLarge(
text: "${widget.model.temperature}° C",
style: context.bodyLarge.copyWith(
color: ColorsManager.primaryColor.withOpacity(0.6),
fontSize: 23,
),
),
SizedBox.square(
dimension: 24,
child: InkWell(
onTap: () {
setState(() {
// temp = temp + .5
widget.model.temperature = widget.model.temperature + .5;
});
},
child: SvgPicture.asset(
Assets.iconsPlus,
height: 24,
width: 24,
),
),
),
],
),
);
}
}
@@ -3,7 +3,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/view/widgets/categories_view.dart';
import '../../bloc/devices_cubit.dart';
import 'no_devices_view.dart';
class DevicesViewBody extends StatelessWidget {
const DevicesViewBody({
@@ -13,17 +12,15 @@ class DevicesViewBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => DevicesCubit(),
child: BlocBuilder<DevicesCubit, DevicesState>(
builder: (context, state) {
return state is DevicesLoading
? const Center(child: CircularProgressIndicator())
: state is DevicesSuccess
? DevicesCubit.get(context).categories.isEmpty
? const NoDevicesView()
: const CategoriesView()
: const Center(child: Text('Error'));
},
));
create: (context) => DevicesCubit(),
child: BlocBuilder<DevicesCubit, DevicesState>(
builder: (context, state) {
return state is DevicesLoading
? const Center(child: CircularProgressIndicator())
: DevicesCubit.get(context).chosenCategory ??
const CategoriesView();
},
),
);
}
}
@@ -0,0 +1,10 @@
import 'package:flutter/material.dart';
class DoorView extends StatelessWidget {
const DoorView({super.key});
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
@@ -0,0 +1,10 @@
import 'package:flutter/material.dart';
class GateWayView extends StatelessWidget {
const GateWayView({super.key});
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
@@ -0,0 +1,10 @@
import 'package:flutter/material.dart';
class LightsView extends StatelessWidget {
const LightsView({super.key});
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
@@ -1,7 +1,7 @@
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/utils/resource_manager/assets_manager.dart';
import 'package:syncrow_app/generated/assets.dart';
class NoDevicesView extends StatelessWidget {
const NoDevicesView({
@@ -15,7 +15,7 @@ class NoDevicesView extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
ImageManager.boxEmpty,
Assets.imagesBoxEmpty,
opacity: const AlwaysStoppedAnimation(0.5),
scale: 1,
width: 140,
@@ -0,0 +1,10 @@
import 'package:flutter/material.dart';
class ScreensView extends StatelessWidget {
const ScreensView({super.key});
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
+54 -44
View File
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_app/features/shared_widgets/custom_switch.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
@@ -13,51 +14,60 @@ class Switches extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 1.5,
),
padding: const EdgeInsets.only(top: 10),
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: DevicesCubit.get(context).categories.length,
itemBuilder: (context, index) {
return DefaultContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SvgPicture.asset(
DevicesCubit.get(context).categories[index].icon,
fit: BoxFit.contain,
),
SizedBox(
width: 30,
height: 20,
child: CustomSwitch(
value: DevicesCubit.get(context)
.categories[index]
.switchValue,
onChanged: (value) => DevicesCubit.get(context)
.changeSwitchValue(
DevicesCubit.get(context).categories[index].type),
),
),
],
),
BodyLarge(
text: DevicesCubit.get(context).categories[index].name,
fontWeight: FontWeight.bold,
)
],
return BlocBuilder<DevicesCubit, DevicesState>(
builder: (context, state) {
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 1.5,
),
padding: const EdgeInsets.only(top: 10),
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: DevicesCubit.categories.length,
itemBuilder: (_, index) {
return InkWell(
onTap: () => DevicesCubit.get(context).updateCategory(index),
child: DefaultContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SvgPicture.asset(
DevicesCubit.categories[index].icon,
fit: BoxFit.contain,
),
const SizedBox(
width: 30,
height: 20,
child: CustomSwitch(
// value: DevicesCubit
// .categories[index]
// .switchValue,
//
// onChanged: (value) => DevicesCubit.get(context)
// .changeSwitchValue( DevicesCubit
// .categories[index]
// .switchValue),
),
),
],
),
BodyLarge(
text: DevicesCubit.categories[index].name,
fontWeight: FontWeight.bold,
)
],
),
),
);
},
);
},
);
@@ -0,0 +1,70 @@
import 'package:flutter/material.dart';
import '../../../../utils/resource_manager/color_manager.dart';
import '../../../shared_widgets/text_widgets/body_medium.dart';
import '../../bloc/ac_cubit.dart';
class UniversalACSwitch extends StatelessWidget {
const UniversalACSwitch({
super.key,
});
@override
Widget build(BuildContext context) {
bool acsStatus = AcCubit.get(context).areAllACsOff();
//TODO: Move these to String Manager "ON" and "OFF"
return Row(
children: <Widget>[
Expanded(
child: InkWell(
onTap: () {
AcCubit.get(context).turnAllACsOn();
},
child: Container(
height: 60,
decoration: BoxDecoration(
color: acsStatus ? ColorsManager.primaryColor : Colors.white,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(15),
bottomLeft: Radius.circular(15),
),
),
child: Center(
child: BodyMedium(
text: "ON",
fontColor: acsStatus ? Colors.white : null,
fontWeight: FontWeight.bold,
),
),
),
),
),
Expanded(
child: InkWell(
onTap: () {
AcCubit.get(context).turnAllACsOff();
},
child: Container(
height: 60,
decoration: BoxDecoration(
color: acsStatus ? Colors.white : ColorsManager.primaryColor,
borderRadius: const BorderRadius.only(
topRight: Radius.circular(15),
bottomRight: Radius.circular(15),
),
),
child: Center(
child: BodyMedium(
text: "OFF",
fontColor: acsStatus ? null : Colors.white,
fontWeight: FontWeight.bold,
),
),
),
),
),
],
);
}
}
@@ -0,0 +1,59 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_app/features/devices/bloc/ac_cubit.dart';
import 'package:syncrow_app/utils/context_extension.dart';
import '../../../../generated/assets.dart';
import '../../../../utils/resource_manager/color_manager.dart';
import '../../../shared_widgets/default_container.dart';
import '../../../shared_widgets/text_widgets/body_large.dart';
class UniversalACTemp extends StatelessWidget {
const UniversalACTemp({
super.key,
});
@override
Widget build(BuildContext context) {
double averageTemp = AcCubit.get(context).averageTempForAll();
return DefaultContainer(
height: 60,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
SizedBox.square(
dimension: 24,
child: InkWell(
onTap: () {
AcCubit.get(context).setTempToAll(averageTemp + .5);
},
child: SvgPicture.asset(
Assets.iconsMinus,
),
),
),
BodyLarge(
text: "${AcCubit.get(context).averageTempForAll()}° C",
style: context.bodyLarge.copyWith(
color: ColorsManager.primaryColor.withOpacity(0.6),
fontSize: 23,
),
),
SizedBox.square(
dimension: 24,
child: InkWell(
onTap: () {
AcCubit.get(context).setTempToAll(averageTemp + .5);
},
child: SvgPicture.asset(
Assets.iconsPlus,
height: 24,
width: 24,
),
),
),
],
),
);
}
}
+9 -8
View File
@@ -8,13 +8,14 @@ class LayoutPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => LayoutCubit(),
child: BlocBuilder<LayoutCubit, LayoutState>(
builder: (context, state) {
return const Center(
child: Text('Layout Page'),
);
},
));
create: (context) => LayoutCubit(),
child: BlocBuilder<LayoutCubit, LayoutState>(
builder: (context, state) {
return const Center(
child: Text('Layout Page'),
);
},
),
);
}
}
+7 -4
View File
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/menu/bloc/menu_cubit.dart';
import 'package:syncrow_app/features/menu/view/widgets/menu_list.dart';
import 'package:syncrow_app/features/menu/view/widgets/profile_tab.dart';
class MenuView extends StatelessWidget {
const MenuView({super.key});
@@ -15,10 +16,12 @@ class MenuView extends StatelessWidget {
return SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
children: MenuCubit.of(context)
.menuLists
.map((list) => MenuList(listModel: list))
.toList(),
children: [
const ProfileTab(),
...MenuCubit.of(context)
.menuLists
.map((list) => MenuList(listModel: list))
],
),
);
},
@@ -19,6 +19,7 @@ class MenuList extends StatelessWidget {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Gap(5),
BodySmall(
text: listModel.label!,
),
@@ -0,0 +1,55 @@
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';
import '../../../shared_widgets/syncrow_logo.dart';
class ProfileTab extends StatelessWidget {
const ProfileTab({
super.key,
});
@override
Widget build(BuildContext context) {
return const Padding(
padding: EdgeInsets.symmetric(vertical: 10),
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Gap(20),
DefaultContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
BodyMedium(
text: "Karim",
fontWeight: FontWeight.bold,
),
BodySmall(text: "Syncrow Account")
],
),
),
],
),
Positioned(
right: 20,
top: 0,
child: CircleAvatar(
radius: 38,
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 37,
backgroundColor: Colors.grey,
child: SyncrowLogo(),
),
),
),
],
),
);
}
}
+1
View File
@@ -13,6 +13,7 @@ class SceneCubit extends Cubit<SceneState> {
void getScenes() {
emit(SceneLoading());
//TODO: remove this it's causing the Bad State because its being after the cubit is closed
Future.delayed(const Duration(seconds: 5), () {
emit(SceneSuccess());
});
+4 -3
View File
@@ -6,7 +6,7 @@ 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';
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
import 'package:syncrow_app/utils/resource_manager/assets_manager.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/strings_manager.dart';
class SceneView extends StatelessWidget {
@@ -51,7 +51,7 @@ class SceneView extends StatelessWidget {
Image.asset(
height: 50,
width: 50,
IconsManager.summerMode,
Assets.iconsHot1,
fit: BoxFit.contain,
),
const Icon(
@@ -79,6 +79,7 @@ class SceneView extends StatelessWidget {
),
child: DefaultContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -87,7 +88,7 @@ class SceneView extends StatelessWidget {
Image.asset(
height: 50,
width: 50,
IconsManager.winterMode,
Assets.iconsWinter1,
fit: BoxFit.contain,
),
const Icon(
@@ -1,7 +1,7 @@
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/utils/resource_manager/assets_manager.dart';
import 'package:syncrow_app/generated/assets.dart';
class SceneViewNoScenes extends StatelessWidget {
const SceneViewNoScenes({
@@ -17,7 +17,7 @@ class SceneViewNoScenes extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
ImageManager.automation,
Assets.imagesAutomation,
scale: 1,
opacity: const AlwaysStoppedAnimation(.5),
width: 140,
+25 -17
View File
@@ -2,10 +2,14 @@ import 'package:flutter/material.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class CustomSwitch extends StatefulWidget {
final bool value;
final ValueChanged<bool> onChanged;
// final bool value;
// final ValueChanged<bool> onChanged;
const CustomSwitch({super.key, required this.value, required this.onChanged});
const CustomSwitch({
super.key,
// required this.value,
// required this.onChanged,
});
@override
_CustomSwitchState createState() => _CustomSwitchState();
@@ -16,14 +20,20 @@ class _CustomSwitchState extends State<CustomSwitch>
Animation? _circleAnimation;
AnimationController? _animationController;
bool value = false;
void onChange(bool customValue){
value = customValue ;
}
@override
void initState() {
super.initState();
_animationController = AnimationController(
vsync: this, duration: const Duration(milliseconds: 100));
_circleAnimation = AlignmentTween(
begin: widget.value ? Alignment.centerRight : Alignment.centerLeft,
end: widget.value ? Alignment.centerLeft : Alignment.centerRight)
begin: value ? Alignment.centerRight : Alignment.centerLeft,
end: value ? Alignment.centerLeft : Alignment.centerRight)
.animate(CurvedAnimation(
parent: _animationController!, curve: Curves.linear));
}
@@ -35,12 +45,14 @@ class _CustomSwitchState extends State<CustomSwitch>
builder: (context, child) {
return GestureDetector(
onTap: () {
_animationController!.isCompleted
? _animationController!.reverse()
: _animationController!.forward();
widget.value == false
? widget.onChanged(true)
: widget.onChanged(false);
setState(() {
_animationController!.isCompleted
? _animationController!.reverse()
: _animationController!.forward();
value == false
? onChange(true)
: onChange(false);
});
},
child: Container(
width: 45.0,
@@ -54,13 +66,9 @@ class _CustomSwitchState extends State<CustomSwitch>
child: Padding(
padding: const EdgeInsets.all(2.0),
child: Container(
alignment: widget.value
? ((Directionality.of(context) == TextDirection.rtl)
alignment: value
? Alignment.centerRight
: Alignment.centerLeft)
: ((Directionality.of(context) == TextDirection.rtl)
? Alignment.centerLeft
: Alignment.centerRight),
: Alignment.centerLeft,
child: Container(
width: 20.0,
height: 20.0,
@@ -4,13 +4,19 @@ class DefaultContainer extends StatelessWidget {
const DefaultContainer({
super.key,
required this.child,
this.height,
this.width,
});
final double? height;
final double? width;
final Widget child;
@override
Widget build(BuildContext context) {
return Container(
height: height,
width: width,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
@@ -0,0 +1,83 @@
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/devices/model/ac_model.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class DevicesDefaultSwitch extends StatefulWidget {
const DevicesDefaultSwitch({
super.key,
required this.model,
});
final ACModel model;
@override
State<DevicesDefaultSwitch> createState() => _DevicesDefaultSwitchState();
}
class _DevicesDefaultSwitchState extends State<DevicesDefaultSwitch> {
@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
Expanded(
child: InkWell(
onTap: () {
setState(() {
// isOn = !isOn;
widget.model.status = !widget.model.status;
});
},
child: Container(
height: 60,
decoration: BoxDecoration(
color: widget.model.status
? ColorsManager.primaryColor
: Colors.white,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(15),
bottomLeft: Radius.circular(15),
),
),
child: Center(
child: BodyMedium(
text: "ON",
fontColor: widget.model.status ? Colors.white : null,
fontWeight: FontWeight.bold,
),
),
),
),
),
Expanded(
child: InkWell(
onTap: () {
setState(() {
widget.model.status = !widget.model.status;
});
},
child: Container(
height: 60,
decoration: BoxDecoration(
color: widget.model.status
? Colors.white
: ColorsManager.primaryColor,
borderRadius: const BorderRadius.only(
topRight: Radius.circular(15),
bottomRight: Radius.circular(15),
),
),
child: Center(
child: BodyMedium(
text: "OFF",
fontColor: widget.model.status ? null : Colors.white,
fontWeight: FontWeight.bold,
),
),
),
),
),
],
);
}
}
@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:syncrow_app/utils/resource_manager/assets_manager.dart';
import 'package:syncrow_app/generated/assets.dart';
class SyncrowLogo extends StatelessWidget {
const SyncrowLogo({
@@ -14,7 +14,7 @@ class SyncrowLogo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Image.asset(isDark ? ImageManager.blackLogo : ImageManager.whiteLogo,
return Image.asset(isDark ? Assets.imagesBlackLogo : Assets.imagesWhiteLogo,
scale: 1, width: width);
}
}
@@ -11,6 +11,7 @@ class BodyLarge extends StatelessWidget {
this.style,
this.height,
this.fontWeight,
this.fontColor,
});
final String text;
@@ -22,11 +23,17 @@ class BodyLarge extends StatelessWidget {
final FontWeight? fontWeight;
final Color? fontColor;
@override
Widget build(BuildContext context) => CustomText(
text,
style: style ?? context.bodyLarge.copyWith(height: height ?? 1.5),
textAlign: textAlign,
fontWeight: fontWeight,
style: style ??
context.bodyLarge.copyWith(
height: height ?? 1.5,
fontWeight: fontWeight,
color: fontColor,
),
);
}
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class CustomText extends StatelessWidget {
const CustomText(this.text,
@@ -31,10 +30,7 @@ class CustomText extends StatelessWidget {
Widget build(BuildContext context) {
return SelectableText(
text,
style: style!.copyWith(
fontSize: fontSize,
color: fontColor ?? ColorsManager.textPrimaryColor,
fontWeight: fontWeight),
style: style,
textAlign: textAlign,
onTap: onTap,
minLines: minLines,
+2 -2
View File
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:syncrow_app/features/splash/view/widgets/user_agreement_dialog.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/navigation/routing_constants.dart';
import 'package:syncrow_app/utils/resource_manager/assets_manager.dart';
class SplashView extends StatelessWidget {
const SplashView({super.key});
@@ -28,7 +28,7 @@ class SplashView extends StatelessWidget {
builder: (context) => const UserAgreementDialog(),
);
},
child: Image.asset(ImageManager.blackLogo)),
child: Image.asset(Assets.imagesBlackLogo)),
),
);
}
+34 -3
View File
@@ -2,20 +2,51 @@
class Assets {
Assets._();
static const String assetsIconsHome = 'assets/icons/home.svg';
static const String fontsAftikaRegular = 'assets/fonts/AftikaRegular.ttf';
static const String iconsDashboard = 'assets/icons/dashboard-fill.svg';
static const String iconsDashboardFill = 'assets/icons/dashboard.svg';
static const String iconsAC = 'assets/icons/AC.svg';
static const String iconsActive = 'assets/icons/active.svg';
static const String iconsCO2 = 'assets/icons/CO2.svg';
static const String iconsColdMode = 'assets/icons/coldMode.svg';
static const String iconsCurtain = 'assets/icons/Curtain.svg';
static const String iconsDashboard = 'assets/icons/dashboard.svg';
static const String iconsDashboardFill = 'assets/icons/dashboard-fill.svg';
static const String iconsDevices = 'assets/icons/Devices.svg';
static const String iconsDevicesFill = 'assets/icons/Devices-fill.svg';
static const String iconsHome = 'assets/icons/home.svg';
static const String iconsDoorLock = 'assets/icons/doorLock.svg';
static const String iconsFan0 = 'assets/icons/fan-0.svg';
static const String iconsFan1 = 'assets/icons/fan-1.svg';
static const String iconsFan2 = 'assets/icons/fan-2.svg';
static const String iconsFan3 = 'assets/icons/fan-3.svg';
static const String iconsFrequency = 'assets/icons/frequency.svg';
static const String iconsGateway = 'assets/icons/Gateway.svg';
static const String iconsHome = 'assets/icons/home.jpg';
static const String iconsHome2 = 'assets/icons/home-2.svg';
static const String iconsHot1 = 'assets/icons/hot1.jpg';
static const String iconsLayout = 'assets/icons/Layout.svg';
static const String iconsLayoutFill = 'assets/icons/Layout-fill.svg';
static const String iconsLight = 'assets/icons/Light.svg';
static const String iconsMenu = 'assets/icons/Menu.svg';
static const String iconsMenuFill = 'assets/icons/Menu-fill.svg';
static const String iconsMinus = 'assets/icons/minus.svg';
static const String iconsPlus = 'assets/icons/plus.svg';
static const String iconsRoutineFill = 'assets/icons/Routine-fill.svg';
static const String iconsRoutines = 'assets/icons/Routines.svg';
static const String iconsScreen = 'assets/icons/Screen.svg';
static const String iconsSummer = 'assets/icons/Summer.svg';
static const String iconsSummerMode = 'assets/icons/summer_mode.svg';
static const String iconsSunnyMode = 'assets/icons/sunnyMode.svg';
static const String iconsSustainability = 'assets/icons/sustainability.svg';
static const String iconsVoltMeter = 'assets/icons/volt-meter.svg';
static const String iconsWindyMode = 'assets/icons/windyMode.svg';
static const String iconsWinter = 'assets/icons/Winter.svg';
static const String iconsWinter1 = 'assets/icons/winter1.jpg';
static const String iconsWinterMode = 'assets/icons/Winter_mode.svg';
static const String imagesAutomation = 'assets/images/automation.jpg';
static const String imagesBackground = 'assets/images/Background.png';
static const String imagesBlackLogo = 'assets/images/black-logo.png';
static const String imagesBoxEmpty = 'assets/images/box-empty.jpg';
static const String imagesTestDash = 'assets/images/test_dash.png';
static const String imagesTestDash2 = 'assets/images/test_dash2.png';
static const String imagesWhiteLogo = 'assets/images/white-logo.png';
}
+5 -1
View File
@@ -1,6 +1,7 @@
// ignore_for_file: avoid_print
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
class MyBlocObserver extends BlocObserver {
@override
@@ -24,6 +25,9 @@ class MyBlocObserver extends BlocObserver {
@override
void onClose(BlocBase bloc) {
super.onClose(bloc);
if (bloc is DevicesCubit) {
DevicesCubit.clearCategoriesSelection();
}
print('onClose -- ${bloc.runtimeType}');
}
}
}
-31
View File
@@ -1,31 +0,0 @@
import 'package:shared_preferences/shared_preferences.dart';
class CacheHelper {
static late SharedPreferences sharedPreferences;
static init() async {
sharedPreferences = await SharedPreferences.getInstance();
}
static Object? getData({
required String key,
}) async {
return sharedPreferences.get(key);
}
static Future setData({
required String key,
required value,
}) async {
if (value is String) return await sharedPreferences.setString(key, value);
if (value is int) return await sharedPreferences.setInt(key, value);
if (value is bool) return await sharedPreferences.setBool(key, value);
return await sharedPreferences.setDouble(key, value);
}
static dynamic removeData({
required String key,
}) async {
return sharedPreferences.remove(key);
}
}
-125
View File
@@ -1,125 +0,0 @@
// import 'dart:io';
// import 'dart:math';
// import 'package:dio/dio.dart';
// import 'package:file_picker/file_picker.dart';
// import 'package:flutter/material.dart';
// import 'package:flutter/services.dart';
//
// import 'package:path_provider/path_provider.dart';
//
// class FileHelper {
// static Future<Map<String, Uint8List>> takePicture() async {
// try {
// XFile? pickedImage = await ImagePicker().pickImage(source: ImageSource.camera);
// if (pickedImage != null) {
// final fileTemp = File(pickedImage.path);
// final bytes = fileTemp.readAsBytesSync();
// return {pickedImage.path: bytes};
// } else {
// return {};
// }
// } on PlatformException catch (_) {
// return {};
// }
// }
//
// static Future<Map<String, Uint8List>> pickFile({bool gallery = false}) async {
// try {
// FilePickerResult? pickedFile;
// XFile? pickedFromGallery;
// if (gallery) {
// final picker = ImagePicker();
// pickedFromGallery =
// await picker.pickImage(source: ImageSource.gallery, requestFullMetadata: false);
// } else {
// pickedFile = await FilePicker.platform.pickFiles(
// allowedExtensions: ['png', 'jpg', 'jpeg', 'pdf'],
// type: FileType.custom,
// withReadStream: true,
// );
// }
// if (pickedFile != null) {
// String path = pickedFile.files.single.path ?? '';
// final fileTemp = File(path);
// final bytes = fileTemp.readAsBytesSync();
// if (path.isEmpty) {
// return {};
// }
// return {path: bytes};
// } else if (pickedFromGallery != null) {
// String path = pickedFromGallery.path;
// final fileTemp = File(path);
// final bytes = fileTemp.readAsBytesSync();
// if (path.isEmpty) {
// return {};
// }
// return {path: bytes};
// } else {
// return {};
// }
// } on PlatformException catch (_) {
// return {};
// }
// }
//
// Future<String> downloadFile(String url) async {
// String filePath;
// try {
// filePath = await _prepareSaveDir(url);
// await HTTPService()
// .downloadRequest(path: url, savePath: filePath, expectedResponseModel: (json) {});
// } catch (err) {
// CustomSnackBar.displaySnackBar('Something went wrong please try again!');
// return '';
// }
// return filePath;
// }
//
// String getRandomString(int length) {
// const chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
// Random rnd = Random();
//
// return String.fromCharCodes(
// Iterable.generate(length, (_) => chars.codeUnitAt(rnd.nextInt(chars.length))));
// }
//
// Future<String> _prepareSaveDir(String url) async {
// try {
// final localPath = (await _findLocalPath(url))!;
//
// final savedDir = Directory(localPath);
// bool hasExisted = await savedDir.exists();
// if (!hasExisted) {
// await File(savedDir.path).create();
// }
// return savedDir.path;
// } catch (err) {
// return '';
// }
// }
//
// Future<String?> _findLocalPath(String url) async {
// String fileName = getRandomString(10);
// String fileNameWithExtension = url.contains('pdf') ? '$fileName.pdf' : '$fileName.jpeg';
//
// if (Platform.isAndroid) {
// return "/sdcard/download/$fileNameWithExtension";
// } else {
// var directory = await getApplicationDocumentsDirectory();
// return '${directory.path}${Platform.pathSeparator}$fileNameWithExtension';
// }
// }
//
// static Future<Uint8List?> fetchPdfContent(final String url) async {
// try {
// final Response<List<int>> response = await Dio().get<List<int>>(
// url,
// options: Options(responseType: ResponseType.bytes),
// );
// return Uint8List.fromList(response.data ?? []);
// } catch (e) {
// debugPrint(e.toString());
// return null;
// }
// }
// }
@@ -1,90 +0,0 @@
import 'package:shared_preferences/shared_preferences.dart';
class SharedPreferencesHelper {
// isRegistered flag to know if the user has entered his fullname and email or not (is he registered or not)
static bool? isRegistered;
// flags to detect the mode {regular, onboarding, demo}
static bool? isDemo;
static bool? isOnBoarding;
// isDemoAndUseToken flag to use the user token in the header of the request in the demo experience, instead of "Demo" header in situations (1. openning the profile request 2. updating th user data -registeration- request)
static bool? isDemoAndUseToken;
// addedFirstProperty flag to detect if the user has added his first property or not
static bool? addedFirstProperty;
// stores the user id value
static String? userIdValue;
// stores the phone number value
static String? phoneNumber;
//stores the country code of the user phone
static String? countryCode;
// static Future<bool?> getIsDemoValue() async {
// isDemo = await readBoolFromSP(KeyConstants.isDemoFlag) ?? false;
// return isDemo;
// }
//
// static Future<bool?> getIsOnboardingValue() async {
// isOnBoarding = await readBoolFromSP(KeyConstants.isOnboardingFlag);
// return isOnBoarding;
// }
static saveStringToSP(String key, String value) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(key, value);
}
static saveBoolToSP(String key, bool value) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(key, value);
}
static saveIntToSP(String key, int value) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setInt(key, value);
}
static saveDoubleToSP(String key, double value) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setDouble(key, value);
}
static saveStringListToSP(String key, List<String> value) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setStringList(key, value);
}
static Future<String> readStringFromSP(String key) async {
final prefs = await SharedPreferences.getInstance();
String value = prefs.getString(key) ?? '';
return value;
}
static Future<bool?> readBoolFromSP(String key) async {
final prefs = await SharedPreferences.getInstance();
bool? value = prefs.getBool(key);
return value;
}
static Future<int> readIntFromSP(String key) async {
final prefs = await SharedPreferences.getInstance();
int value = prefs.getInt(key) ?? 0;
return value;
}
static Future<List<String>> readStringListFromSP(String key) async {
final prefs = await SharedPreferences.getInstance();
List<String>? value = prefs.getStringList(key) ?? [];
return value;
}
static Future<bool> removeValueFromSP(String key) async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove(key);
return true;
}
}
-76
View File
@@ -1,76 +0,0 @@
import 'dart:io';
import 'package:url_launcher/url_launcher.dart';
class URLLauncher {
static Future<void> sendWhatsapp(
{String phoneNumber = '971581497062',
String text = 'Hi%2C%20I%20would%20like%20to',
String from = ''}) async {
Uri launchUri;
launchUri = Uri.parse("whatsapp://send?phone=%2B$phoneNumber&text=$text");
// Launch the App
try {
// SegmentEvents.sendTrackEvent(SegmentEventModel(
// eventName: 'Whatsapp opened', properties: {'From': from}));
//
// if (await canLaunchUrl(launchUri) == false) {
// CustomSnackBar.displaySnackBar('Could not open whatsapp');
// return;
// }
if (Platform.isAndroid) {
await launch(
launchUri.toString(),
);
} else {
await launchUrl(
launchUri,
);
}
} catch (error) {
// CustomSnackBar.displaySnackBar('Could not open whatsapp');
throw 'Could not launch $phoneNumber';
}
}
static Future<void> sendEmail(
{required String email, String subject = '', body = ''}) async {
String? encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((MapEntry<String, String> e) =>
'${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.join('&');
}
final emailLaunchUri = Uri(
scheme: 'mailto',
path: email,
query: encodeQueryParameters(<String, String>{
subject: body,
}),
);
try {
bool canLaunch = await canLaunchUrl(emailLaunchUri);
if (canLaunch) {
await launchUrl(emailLaunchUri);
}
} catch (err) {
throw 'Could not launch $emailLaunchUri';
}
}
static Future<void> launch(String url) async {
Uri parsedUrl = Uri.parse(url);
try {
bool canLaunch = await canLaunchUrl(parsedUrl);
if (canLaunch) {
await launchUrl(
parsedUrl,
// mode: LaunchMode.externalApplication,
);
}
} catch (err) {
throw 'Url launcher error: ${err.toString()}';
}
}
}
@@ -1,47 +0,0 @@
abstract class ImageManager {
static const String base = 'assets/images';
static const String whiteLogo = '$base/white-logo.png';
static const String blackLogo = '$base/black-logo.png';
static const String boxEmpty = '$base/box-empty.jpg';
static const String automation = '$base/automation.jpg';
static const String background = '$base/Background.png';
static const String testDash = '$base/test_dash.png';
static const String testDash2 = '$base/test_dash2.png';
}
abstract class IconsManager {
static const String base = 'assets/icons';
static const String home = '$base/home-2.svg';
static const String dashboardFill = '$base/dashboard-fill.svg';
static const String dashboard = '$base/dashboard.svg';
static const String devices = '$base/Devices.svg';
static const String devicesFill = '$base/Devices-fill.svg';
static const String routine = '$base/Routines.svg';
static const String routineFill = '$base/Routine-fill.svg';
static const String menu = '$base/Menu.svg';
static const String menuFill = '$base/Menu-fill.svg';
static const String layout = '$base/Layout.svg';
static const String layoutFill = '$base/Layout-fill.svg';
static const String frequency = '$base/frequency.svg';
static const String winter = '$base/Winter.svg';
static const String active = '$base/active.svg';
static const String voltMeter = '$base/volt-meter.svg';
static const String summer = '$base/Summer.svg';
static const String CO2 = '$base/CO2.svg';
static const String sustainability = '$base/sustainability.svg';
static const String ac = '$base/AC.svg';
static const String curtain = '$base/Curtain.svg';
static const String doorLock = '$base/Door Lock.svg';
static const String gateway = '$base/Gateway.svg';
static const String light = '$base/Light.svg';
static const String summerMode = '$base/Hot 1.jpg';
static const String winterMode = '$base/Winter 1.jpg';
static const String screen = '$base/Screen.svg';
}