diff --git a/assets/icons/qr_scan.png b/assets/icons/qr_scan.png
deleted file mode 100644
index 7228c7b..0000000
Binary files a/assets/icons/qr_scan.png and /dev/null differ
diff --git a/assets/icons/qr_scan.svg b/assets/icons/qr_scan.svg
deleted file mode 100644
index ba9e926..0000000
--- a/assets/icons/qr_scan.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
diff --git a/lib/features/app_layout/bloc/nav_cubit.dart b/lib/features/app_layout/bloc/nav_cubit.dart
index bb00d0d..87a1967 100644
--- a/lib/features/app_layout/bloc/nav_cubit.dart
+++ b/lib/features/app_layout/bloc/nav_cubit.dart
@@ -33,14 +33,14 @@ class NavCubit extends Cubit {
),
],
'Devices': [
- IconButton(
- icon: Image.asset(
- Assets.iconsFilter,
- height: 20,
- width: 20,
- ),
- onPressed: () {},
- ),
+ // IconButton(
+ // icon: Image.asset(
+ // Assets.iconsFilter,
+ // height: 20,
+ // width: 20,
+ // ),
+ // onPressed: () {},
+ // ),
IconButton(
icon: const Icon(
Icons.add,
@@ -65,14 +65,14 @@ class NavCubit extends Cubit {
),
],
'Routine': [
- IconButton(
- icon: Image.asset(
- Assets.iconsFilter,
- height: 20,
- width: 20,
- ),
- onPressed: () {},
- ),
+ // IconButton(
+ // icon: Image.asset(
+ // Assets.iconsFilter,
+ // height: 20,
+ // width: 20,
+ // ),
+ // onPressed: () {},
+ // ),
IconButton(
icon: const Icon(
Icons.add,
@@ -98,16 +98,8 @@ class NavCubit extends Cubit {
],
'Menu': [
IconButton(
- icon: Image.asset(
- Assets.iconsQrScan,
- height: 20,
- width: 20,
- ),
- onPressed: () {},
- ),
- IconButton(
- icon: Image.asset(
- Assets.iconsSettings,
+ icon: SvgPicture.asset(
+ Assets.iconsScan,
height: 20,
width: 20,
),
@@ -151,6 +143,7 @@ class NavCubit extends Cubit {
void updatePageIndex(int index) {
pageIndex = index;
+ print('index: $index');
pageController.animateToPage(index,
duration: const Duration(milliseconds: 150), curve: Curves.easeIn);
emit(NavChangePage());
diff --git a/lib/features/app_layout/view/widgets/app_body.dart b/lib/features/app_layout/view/widgets/app_body.dart
index a3335a4..e98fa87 100644
--- a/lib/features/app_layout/view/widgets/app_body.dart
+++ b/lib/features/app_layout/view/widgets/app_body.dart
@@ -26,9 +26,7 @@ class AppBody extends StatelessWidget {
),
),
child: PageView(
- onPageChanged: (int index) {
- NavCubit.of(context).updatePageIndex(index);
- },
+ physics: const NeverScrollableScrollPhysics(),
controller: NavCubit.of(context).pageController,
children: NavCubit.of(context).pages,
)
diff --git a/lib/features/app_layout/view/widgets/default_nav_bar.dart b/lib/features/app_layout/view/widgets/default_nav_bar.dart
index 2db04ff..92515db 100644
--- a/lib/features/app_layout/view/widgets/default_nav_bar.dart
+++ b/lib/features/app_layout/view/widgets/default_nav_bar.dart
@@ -1,6 +1,7 @@
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/features/app_layout/bloc/spaces_cubit.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
@@ -24,6 +25,9 @@ class DefaultNavBar extends StatelessWidget {
if (DevicesCubit.get(context).chosenCategoryView != null) {
DevicesCubit().clearCategoriesSelection(context);
}
+ if (SpacesCubit.get(context).selectedRoom != null) {
+ SpacesCubit.get(context).unselectRoom();
+ }
},
currentIndex: NavCubit.pageIndex,
selectedItemColor: ColorsManager.primaryColor,
diff --git a/lib/features/auth/bloc/auth_cubit.dart b/lib/features/auth/bloc/auth_cubit.dart
index e82e3d3..95d6115 100644
--- a/lib/features/auth/bloc/auth_cubit.dart
+++ b/lib/features/auth/bloc/auth_cubit.dart
@@ -2,11 +2,13 @@ import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:syncrow_app/features/auth/model/login_with_email_model.dart';
import 'package:syncrow_app/features/auth/model/token.dart';
import 'package:syncrow_app/features/auth/model/user_model.dart';
import 'package:syncrow_app/services/api/authentication_api.dart';
import 'package:syncrow_app/services/api/network_exception.dart';
+import 'package:syncrow_app/utils/resource_manager/constants.dart';
part 'auth_state.dart';
@@ -50,7 +52,10 @@ class AuthCubit extends Cubit {
);
if (token.accessTokenIsNotEmpty) {
- //Map dictionary
+ FlutterSecureStorage storage = const FlutterSecureStorage();
+ await storage.write(
+ key: Constants.tokenAccessKey, value: token.accessToken);
+
user = UserModel.fromToken(token);
emit(AuthSuccess());
} else {
@@ -60,4 +65,15 @@ class AuthCubit extends Cubit {
throw ServerFailure.fromDioError(e);
}
}
+
+ logout() async {
+ emit(AuthLoading());
+ try {
+ FlutterSecureStorage storage = const FlutterSecureStorage();
+ await storage.delete(key: Constants.tokenAccessKey);
+ emit(AuthLoggedOut());
+ } on DioException catch (e) {
+ throw ServerFailure.fromDioError(e);
+ }
+ }
}
diff --git a/lib/features/auth/bloc/auth_state.dart b/lib/features/auth/bloc/auth_state.dart
index a48552c..8a370b0 100644
--- a/lib/features/auth/bloc/auth_state.dart
+++ b/lib/features/auth/bloc/auth_state.dart
@@ -16,6 +16,8 @@ class AuthError extends AuthState {
class AuthSuccess extends AuthState {}
+class AuthLoggedOut extends AuthState {}
+
class AuthPasswordVisibilityChanged extends AuthState {}
class AuthAgreeToTermsChanged extends AuthState {}
diff --git a/lib/features/auth/model/user_model.dart b/lib/features/auth/model/user_model.dart
index baf44af..4d003a5 100644
--- a/lib/features/auth/model/user_model.dart
+++ b/lib/features/auth/model/user_model.dart
@@ -49,7 +49,7 @@ class UserModel {
Map tempJson = token.decodeToken();
return UserModel(
- id: tempJson['userId'].toString(),
+ id: tempJson['uuid'].toString(),
email: tempJson['email'],
name: null,
photoUrl: null,
diff --git a/lib/features/devices/view/widgets/devices_view_body.dart b/lib/features/devices/view/widgets/devices_view_body.dart
index 7b53425..35858b7 100644
--- a/lib/features/devices/view/widgets/devices_view_body.dart
+++ b/lib/features/devices/view/widgets/devices_view_body.dart
@@ -65,12 +65,10 @@ class DevicesViewBody extends StatelessWidget {
SpacesCubit.get(context).devicesPageController,
count: 3,
effect: const WormEffect(
+ paintStyle: PaintingStyle.stroke,
dotHeight: 8,
dotWidth: 8,
),
- onDotClicked: (index) {
- SpacesCubit.get(context).unselectRoom();
- },
),
),
],
diff --git a/lib/features/devices/view/widgets/rooms_slider.dart b/lib/features/devices/view/widgets/rooms_slider.dart
index 5e9c3d9..8941e6c 100644
--- a/lib/features/devices/view/widgets/rooms_slider.dart
+++ b/lib/features/devices/view/widgets/rooms_slider.dart
@@ -67,58 +67,6 @@ class RoomsSlider extends StatelessWidget {
],
),
);
-
- // SingleChildScrollView(
- // controller: SpacesCubit.get(context).roomsScrollController,
- // scrollDirection: Axis.horizontal,
- // child: Row(
- // mainAxisAlignment: MainAxisAlignment.start,
- // children: [
- // Padding(
- // padding: const EdgeInsets.symmetric(horizontal: 15),
- // child: InkWell(
- // onTap: () {
- // SpacesCubit.get(context).unselectRoom();
- // },
- // child: TitleMedium(
- // text: StringsManager.wizard,
- // style: context.titleMedium.copyWith(
- // fontSize: 25,
- // color: SpacesCubit.get(context).selectedRoom == null
- // ? ColorsManager.textPrimaryColor
- // : ColorsManager.textPrimaryColor.withOpacity(.2),
- // ),
- // ),
- // ),
- // ),
- // ...SpacesCubit.get(context).selectedSpace.rooms.map(
- // (room) => Padding(
- // padding: const EdgeInsets.symmetric(horizontal: 15),
- // child: InkWell(
- // onTap: () {
- // SpacesCubit.get(context).selectRoom(room);
- // },
- // child: TitleMedium(
- // text: room.name,
- // style: context.titleMedium.copyWith(
- // fontSize: 25,
- // color: SpacesCubit.get(context).selectedRoomIndex ==
- // SpacesCubit.get(context)
- // .selectedSpace
- // .rooms
- // .indexOf(room) +
- // 1
- // ? ColorsManager.textPrimaryColor
- // : ColorsManager.textPrimaryColor
- // .withOpacity(.2),
- // ),
- // ),
- // ),
- // ),
- // )
- // ],
- // ),
- // );
},
);
}
diff --git a/lib/features/menu/view/menu_view.dart b/lib/features/menu/view/menu_view.dart
index 2a491dc..1c55a36 100644
--- a/lib/features/menu/view/menu_view.dart
+++ b/lib/features/menu/view/menu_view.dart
@@ -1,8 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:syncrow_app/features/auth/bloc/auth_cubit.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';
+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/navigation/routing_constants.dart';
+import 'package:syncrow_app/utils/context_extension.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class MenuView extends StatelessWidget {
@@ -14,26 +19,56 @@ class MenuView extends StatelessWidget {
create: (BuildContext context) => MenuCubit(),
child: BlocBuilder(
builder: (context, state) {
- return Padding(
- padding: EdgeInsets.only(
- top: Constants.appBarHeight,
- bottom: Constants.bottomNavBarHeight,
- left: Constants.defaultPadding,
- right: Constants.defaultPadding,
- ),
- child: SingleChildScrollView(
- physics: const BouncingScrollPhysics(),
- child: Column(
- children: [
- const ProfileTab(),
- ...MenuCubit.of(context).menuLists.map(
- (list) => MenuList(
- listModel: list,
- ),
+ return BlocBuilder(
+ builder: (context, state) {
+ return Padding(
+ padding: EdgeInsets.only(
+ top: Constants.appBarHeight,
+ bottom: Constants.bottomNavBarHeight,
+ left: Constants.defaultPadding,
+ right: Constants.defaultPadding,
+ ),
+ child: SingleChildScrollView(
+ physics: const BouncingScrollPhysics(),
+ child: Column(
+ children: [
+ const ProfileTab(),
+ ...MenuCubit.of(context).menuLists.map(
+ (list) => MenuList(
+ listModel: list,
+ ),
+ ),
+ const SizedBox(
+ height: 15,
),
- ],
- ),
- ),
+ InkWell(
+ onTap: () {
+ AuthCubit.get(context).logout();
+ Navigator.of(context).pushNamedAndRemoveUntil(
+ Routes.authLogin, (route) => false);
+ },
+ child: Row(
+ children: [
+ Expanded(
+ child: DefaultContainer(
+ child: Center(
+ child: BodyLarge(
+ text: 'Logout',
+ style: context.bodyLarge.copyWith(
+ color: Colors.red,
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ )
+ ],
+ ),
+ ),
+ );
+ },
);
},
),
diff --git a/lib/features/shared_widgets/default_button.dart b/lib/features/shared_widgets/default_button.dart
index cbb70ce..05bcf7d 100644
--- a/lib/features/shared_widgets/default_button.dart
+++ b/lib/features/shared_widgets/default_button.dart
@@ -13,6 +13,8 @@ class DefaultButton extends StatelessWidget {
this.isDone = false,
this.customTextStyle,
this.customButtonStyle,
+ this.backgroundColor,
+ this.foregroundColor,
});
final void Function()? onPressed;
@@ -29,6 +31,10 @@ class DefaultButton extends StatelessWidget {
final ButtonStyle? customButtonStyle;
+ final Color? backgroundColor;
+
+ final Color? foregroundColor;
+
@override
Widget build(BuildContext context) {
return ElevatedButton(
@@ -41,17 +47,22 @@ class DefaultButton extends StatelessWidget {
customTextStyle ??
context.bodyMedium.copyWith(
fontSize: 16,
+ color: foregroundColor,
),
),
foregroundColor: MaterialStateProperty.all(
isSecondary
? Colors.black
: enabled
- ? Colors.white
+ ? foregroundColor ?? Colors.white
: Colors.black,
),
- backgroundColor: MaterialStateProperty.all(
- enabled ? ColorsManager.primaryColor : Colors.grey),
+ backgroundColor: MaterialStateProperty.resolveWith(
+ (Set states) {
+ return enabled
+ ? backgroundColor ?? ColorsManager.primaryColor
+ : Colors.grey;
+ }),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
diff --git a/lib/features/splash/view/splash_view.dart b/lib/features/splash/view/splash_view.dart
index 218bc63..d36745f 100644
--- a/lib/features/splash/view/splash_view.dart
+++ b/lib/features/splash/view/splash_view.dart
@@ -1,7 +1,9 @@
import 'package:flutter/material.dart';
+import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/navigation/routing_constants.dart';
+import 'package:syncrow_app/utils/resource_manager/constants.dart';
class SplashView extends StatelessWidget {
const SplashView({super.key});
@@ -9,15 +11,16 @@ class SplashView extends StatelessWidget {
@override
Widget build(BuildContext context) {
//TODO remove this delay
- Future.delayed(
- const Duration(seconds: 5),
- () {
- Navigator.popAndPushNamed(
- context,
- Routes.authLogin,
- );
- },
- );
+ Future.value().then((value) async {
+ var isLoggedIn = await const FlutterSecureStorage()
+ .read(key: Constants.tokenAccessKey) !=
+ null;
+ if (isLoggedIn) {
+ Navigator.pushReplacementNamed(context, Routes.homeRoute);
+ } else {
+ Navigator.pushReplacementNamed(context, Routes.authLogin);
+ }
+ });
return Scaffold(
body: Stack(
alignment: Alignment.center,
diff --git a/lib/generated/assets.dart b/lib/generated/assets.dart
index 8237caa..b3da647 100644
--- a/lib/generated/assets.dart
+++ b/lib/generated/assets.dart
@@ -2,7 +2,6 @@
class Assets {
Assets._();
- static const String assetsIconsQrScan = 'assets/icons/qr_scan.svg';
static const String assetsIconsSettings = 'assets/icons/settings.svg';
static const String fontsAftikaRegular = 'assets/fonts/AftikaRegular.ttf';
static const String iconsAC = 'assets/icons/AC.svg';
@@ -38,9 +37,9 @@ class Assets {
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 iconsQrScan = 'assets/icons/qr_scan.png';
static const String iconsRoutines = 'assets/icons/Routines.svg';
static const String iconsRoutinesFill = 'assets/icons/Routines-fill.svg';
+ static const String iconsScan = 'assets/icons/Scan.svg';
static const String iconsScreen = 'assets/icons/Screen.svg';
static const String iconsSettings = 'assets/icons/settings.png';
static const String iconsSummer = 'assets/icons/Summer.svg';
diff --git a/lib/main.dart b/lib/main.dart
index edb3229..2fa8e01 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -2,9 +2,11 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:syncrow_app/services/locator.dart';
import 'package:syncrow_app/utils/bloc_observer.dart';
import 'package:syncrow_app/utils/helpers/localization_helpers.dart';
+import 'package:syncrow_app/utils/resource_manager/constants.dart';
import 'my_app.dart';
@@ -32,6 +34,13 @@ void main() {
//to initialize the locator
initialSetup();
+ //final SharedPreferences prefs = await SharedPreferences.getInstance();
+ // var isLoggedIn = (prefs.getBool('isLoggedIn') == null) ? false : prefs.getBool('isLoggedIn');
+ //
+ var storage = const FlutterSecureStorage();
+ bool isLoggedIn =
+ await (storage.read(key: Constants.tokenAccessKey)) != null;
+
//to save the locale in the shared preferences
await LocalizationService.saveLocale(const Locale("en", "AE"));
final savedLocale = await LocalizationService.savedLocale();
diff --git a/lib/utils/resource_manager/constants.dart b/lib/utils/resource_manager/constants.dart
index b185b28..6327b1b 100644
--- a/lib/utils/resource_manager/constants.dart
+++ b/lib/utils/resource_manager/constants.dart
@@ -11,7 +11,7 @@ abstract class Constants {
static const double defaultPadding = 16;
- static const String tokenKey = 'userToken';
+ static const String tokenAccessKey = 'access_token';
}
enum DeviceType {