diff --git a/android/build.gradle b/android/build.gradle index 792628c..e83fb5d 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.9.23' + ext.kotlin_version = '1.7.10' repositories { google() mavenCentral() diff --git a/lib/features/app_layout/view/widgets/default_app_bar.dart b/lib/features/app_layout/view/widgets/default_app_bar.dart index 29f003e..2d29b96 100644 --- a/lib/features/app_layout/view/widgets/default_app_bar.dart +++ b/lib/features/app_layout/view/widgets/default_app_bar.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; - +import 'package:flutter_svg/svg.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; +import 'package:syncrow_app/features/app_layout/model/space_model.dart'; +import 'package:syncrow_app/generated/assets.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart'; class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget { @@ -19,10 +22,21 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget { backgroundColor: Colors.transparent, leadingWidth: 200, toolbarHeight: Constants.appBarHeight, - leading: HomeCubit.getInstance().spaces!.isNotEmpty - ? HomeCubit.appBarLeading[HomeCubit.bottomNavItems[HomeCubit.pageIndex].label]! - : null, - actions: HomeCubit.appBarActions[HomeCubit.bottomNavItems[HomeCubit.pageIndex].label], + leading: InkWell( + onTap: () { + final spaces = HomeCubit.getInstance().spaces!; + showSpaceBottomSheet(context, spaces); + }, + child: HomeCubit.getInstance().spaces!.isNotEmpty + ? AbsorbPointer( + absorbing: true, + child: HomeCubit.appBarLeading[HomeCubit + .bottomNavItems[HomeCubit.pageIndex].label]!, + ) + : null, + ), + actions: HomeCubit.appBarActions[ + HomeCubit.bottomNavItems[HomeCubit.pageIndex].label], )); }, ); @@ -31,3 +45,83 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget { @override Size get preferredSize => Size.fromHeight(Constants.appBarHeight); } + +void showSpaceBottomSheet(BuildContext context, List spaces) { + showModalBottomSheet( + isScrollControlled: true, + context: context, + builder: (BuildContext context) { + return StatefulBuilder( + builder: (BuildContext context, StateSetter setModalState) { + String? selectedSpaceId = HomeCubit.getInstance().selectedSpace?.id; + final bool shouldLimitHeight = spaces.length > 5; + return Container( + constraints: shouldLimitHeight + ? BoxConstraints( + maxHeight: MediaQuery.of(context).size.height * 0.5, + ) + : const BoxConstraints(), + child: SingleChildScrollView( + child: Column( + children: [ + const SizedBox(height: 10), + Container( + decoration: const BoxDecoration(color: Colors.black12), + height: 5, + width: 50, + ), + ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: spaces.length, + itemBuilder: (BuildContext context, int index) { + final space = spaces[index]; + return Padding( + padding: const EdgeInsets.only(left: 30, right: 30), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Text(space.name), + ], + ), + Radio( + value: space.id, + groupValue: selectedSpaceId, + onChanged: (String? newValue) { + if (newValue != null) { + setModalState(() { + selectedSpaceId = newValue; + }); + HomeCubit.getInstance().changeSelectedSpace( + spaces.firstWhere((s) => s.id == newValue), + ); + Navigator.of(context).pop(); + } + }, + ), + ], + ), + ); + }, + separatorBuilder: (BuildContext context, int index) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 50), + child: const Divider( + color: Colors.grey, + thickness: 0.5, + ), + ); + }, + ), + ], + ), + ), + ); + }, + ); + }, + ); +} diff --git a/lib/features/auth/view/sign_up_view.dart b/lib/features/auth/view/sign_up_view.dart index 567b0ea..9ef9350 100644 --- a/lib/features/auth/view/sign_up_view.dart +++ b/lib/features/auth/view/sign_up_view.dart @@ -11,6 +11,7 @@ import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.da import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/navigation/routing_constants.dart'; import 'package:syncrow_app/utils/context_extension.dart'; +import 'package:syncrow_app/utils/resource_manager/color_manager.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart'; import 'package:syncrow_app/utils/resource_manager/font_manager.dart'; import 'package:syncrow_app/utils/resource_manager/styles_manager.dart'; @@ -212,11 +213,14 @@ class SignUpView extends StatelessWidget { TextSpan( text: 'By signing up you agree to our ', - style: const TextStyle( - color: Colors.white, - fontSize: 14, - fontWeight: FontWeight.w400, - ), + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith( + fontSize: 16, + color: ColorsManager + .onPrimaryColor, + ), children: [ WidgetSpan( child: GestureDetector( @@ -227,27 +231,34 @@ class SignUpView extends StatelessWidget { const UserAgreement(), )); }, - child: const Text( - 'Terms & Conditions', - style: TextStyle( - fontSize: 16, - color: Colors.white, - fontWeight: FontWeight.w400, - decoration: TextDecoration - .underline, - decorationColor: - Colors.white, - ), + child: BodyMedium( + text: 'Terms & Conditions', + style: Theme.of(context) + .textTheme + .bodyMedium + ?.copyWith( + decoration: + TextDecoration + .underline, + decorationColor: + ColorsManager + .onPrimaryColor, + color: ColorsManager + .onPrimaryColor, + fontSize: 16), ), ), ), - const TextSpan( - text: ' and ', - style: TextStyle( - fontWeight: FontWeight.w400, - fontSize: 16, - color: Colors.white), - ), + TextSpan( + text: ' and ', + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith( + fontSize: 16, + color: ColorsManager + .onPrimaryColor, + )), WidgetSpan( child: GestureDetector( onTap: () { @@ -257,17 +268,20 @@ class SignUpView extends StatelessWidget { const PrivacyPolicy(), )); }, - child: const Text( - 'Privacy Policy', - style: TextStyle( - fontSize: 16, - color: Colors.white, - fontWeight: FontWeight.w400, - decoration: TextDecoration - .underline, - decorationColor: - Colors.white, - ), + child: BodyMedium( + text: 'Privacy Policy', + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith( + decoration: + TextDecoration + .underline, + decorationColor: + Colors.white, + color: ColorsManager + .onPrimaryColor, + fontSize: 16), ), ), ), diff --git a/lib/features/devices/view/widgets/scene_listview.dart b/lib/features/devices/view/widgets/scene_listview.dart index 8cf02cb..9cb7f8e 100644 --- a/lib/features/devices/view/widgets/scene_listview.dart +++ b/lib/features/devices/view/widgets/scene_listview.dart @@ -1,14 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_app/features/scene/bloc/create_scene/create_scene_bloc.dart'; -import 'package:syncrow_app/features/scene/bloc/smart_scene/smart_scene_select_dart_bloc.dart'; -import 'package:syncrow_app/features/scene/enum/create_scene_enum.dart'; -import 'package:syncrow_app/features/scene/model/scene_settings_route_arguments.dart'; +import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_bloc.dart'; +import 'package:syncrow_app/features/scene/bloc/scene_bloc/scene_event.dart'; import 'package:syncrow_app/features/scene/model/scenes_model.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/generated/assets.dart'; -import 'package:syncrow_app/navigation/routing_constants.dart'; class SceneListview extends StatelessWidget { final List scenes; @@ -31,23 +28,28 @@ class SceneListview extends StatelessWidget { padding: const EdgeInsets.only(right: 10), child: DefaultContainer( onTap: () { - Navigator.pushNamed( - context, - Routes.sceneTasksRoute, - arguments: SceneSettingsRouteArguments( - sceneType: CreateSceneEnum.tabToRun.name, - sceneId: scene.id, - sceneName: scene.name, - ), - ); - context.read().add(const SmartSceneClearEvent()); + context + .read() + .add(SceneTrigger(scene.id, scene.name)); + // Navigator.pushNamed( + // context, + // Routes.sceneTasksRoute, + // arguments: SceneSettingsRouteArguments( + // sceneType: CreateSceneEnum.tabToRun.name, + // sceneId: scene.id, + // sceneName: scene.name, + // ), + // ); + // context.read() + // .add(const SmartSceneClearEvent()); - BlocProvider.of(context) - .add(FetchSceneTasksEvent(sceneId: scene.id, isAutomation: false)); + // BlocProvider.of(context).add( + // FetchSceneTasksEvent( + // sceneId: scene.id, isAutomation: false)); - /// the state to set the scene type must be after the fetch - BlocProvider.of(context) - .add(const SceneTypeEvent(CreateSceneEnum.tabToRun)); + // /// the state to set the scene type must be after the fetch + // BlocProvider.of(context) + // .add(const SceneTypeEvent(CreateSceneEnum.tabToRun)); }, child: SizedBox( width: MediaQuery.of(context).size.width * 0.4, @@ -62,7 +64,8 @@ class SceneListview extends StatelessWidget { height: 32, width: 32, fit: BoxFit.fill, - errorBuilder: (context, error, stackTrace) => Image.asset( + errorBuilder: (context, error, stackTrace) => + Image.asset( Assets.assetsIconsLogo, height: 32, width: 32, diff --git a/lib/features/menu/bloc/privacy_policy.dart b/lib/features/menu/bloc/privacy_policy.dart index 0bdfe45..154699a 100644 --- a/lib/features/menu/bloc/privacy_policy.dart +++ b/lib/features/menu/bloc/privacy_policy.dart @@ -1,17 +1,26 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; +import 'package:flutter_html/flutter_html.dart'; import 'package:syncrow_app/features/menu/bloc/menu_cubit.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; import 'package:url_launcher/url_launcher.dart'; -class PrivacyPolicy extends StatelessWidget { +class PrivacyPolicy extends StatefulWidget { const PrivacyPolicy({super.key}); + @override + _PrivacyPolicyState createState() => _PrivacyPolicyState(); +} + +class _PrivacyPolicyState extends State { + @override + void initState() { + super.initState(); + MenuCubit.of(context).fetchPrivacyPolicy(); + } + @override Widget build(BuildContext context) { - final menuCubit = MenuCubit.of(context); - menuCubit.fetchPrivacyPolicy(); return DefaultScaffold( title: 'Privacy Policy', child: BlocBuilder( @@ -21,12 +30,13 @@ class PrivacyPolicy extends StatelessWidget { } else if (state is MenuLoaded) { return ListView( children: [ - HtmlWidget( - state.userAgreementHtml, - onTapUrl: (url) async { - final uri = Uri.parse(url); + Html( + data: state.userAgreementHtml.isNotEmpty + ? state.userAgreementHtml + : '', + onLinkTap: (url, attributes, element) async { + final uri = Uri.parse(url!); await launchUrl(uri, mode: LaunchMode.externalApplication); - return true; }, ), ], diff --git a/lib/features/menu/bloc/user_agreement.dart b/lib/features/menu/bloc/user_agreement.dart index 10a76ff..da4c41c 100644 --- a/lib/features/menu/bloc/user_agreement.dart +++ b/lib/features/menu/bloc/user_agreement.dart @@ -1,17 +1,26 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; +import 'package:flutter_html/flutter_html.dart'; import 'package:syncrow_app/features/menu/bloc/menu_cubit.dart'; import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart'; import 'package:url_launcher/url_launcher.dart'; -class UserAgreement extends StatelessWidget { +class UserAgreement extends StatefulWidget { const UserAgreement({super.key}); + @override + _UserAgreementState createState() => _UserAgreementState(); +} + +class _UserAgreementState extends State { + @override + void initState() { + super.initState(); + MenuCubit.of(context).fetchAgreement(); + } + @override Widget build(BuildContext context) { - final menuCubit = MenuCubit.of(context); - menuCubit.fetchAgreement(); return DefaultScaffold( title: 'User Agreement', child: BlocBuilder( @@ -21,13 +30,13 @@ class UserAgreement extends StatelessWidget { } else if (state is MenuLoaded) { return ListView( children: [ - HtmlWidget( - state - .userAgreementHtml, - onTapUrl: (url) async { - final uri = Uri.parse(url); + Html( + data: state.userAgreementHtml.isNotEmpty + ? state.userAgreementHtml + : '', + onLinkTap: (url, attributes, element) async { + final uri = Uri.parse(url!); await launchUrl(uri, mode: LaunchMode.externalApplication); - return true; }, ), ], diff --git a/pubspec.yaml b/pubspec.yaml index 91ac576..684deba 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -47,8 +47,7 @@ dependencies: fl_chart: ^0.69.0 firebase_database: ^10.5.7 percent_indicator: ^4.2.3 - flutter_widget_from_html: ^0.15.3 - + flutter_html: ^3.0.0-beta.2 dev_dependencies: