diff --git a/assets/images/stay.jpg b/assets/images/stay.jpg new file mode 100644 index 0000000..ae29580 Binary files /dev/null and b/assets/images/stay.jpg differ diff --git a/lib/provider/getit.dart b/lib/provider/getit.dart index da1e8e9..8a73299 100644 --- a/lib/provider/getit.dart +++ b/lib/provider/getit.dart @@ -2,6 +2,7 @@ import 'package:domus/service/navigation_service.dart'; import 'package:domus/view/home_screen_view_model.dart'; import 'package:domus/view/smart_ac_view_model.dart'; import 'package:domus/view/smart_light_view_model.dart'; +import 'package:domus/view/smart_speaker_view_model.dart'; import 'package:get_it/get_it.dart'; GetIt getIt = GetIt.instance; @@ -10,4 +11,5 @@ void setupLocator() { getIt.registerFactory(() => HomeScreenViewModel()); getIt.registerFactory(() => SmartLightViewModel()); getIt.registerFactory(() => SmartACViewModel()); + getIt.registerFactory(() => SmartSpeakerViewModel()); } diff --git a/lib/src/screens/smart_light/components/body.dart b/lib/src/screens/smart_light/components/body.dart index f699e69..5ced040 100644 --- a/lib/src/screens/smart_light/components/body.dart +++ b/lib/src/screens/smart_light/components/body.dart @@ -99,63 +99,6 @@ class Body extends StatelessWidget { SizedBox( height: getProportionateScreenHeight(40), ), - InkWell( - onTap: () { - Navigator.of(context).pop(); - }, - child: Icon(Icons.arrow_back_outlined)), - Stack( - children: [ - Text( - 'Living\nRoom', - style: Theme.of(context).textTheme.headline1!.copyWith( - fontSize: 45, - color: Color(0xFFBDBDBD).withOpacity(0.5), - ), - ), - Text( - 'Living\nRoom', - style: Theme.of(context).textTheme.headline1, - ), - ], - ), - SizedBox( - height: getProportionateScreenHeight(26), - ), - Text( - 'Power', - style: Theme.of(context).textTheme.headline2, - ), - SizedBox( - height: getProportionateScreenHeight(4), - ), - Switch.adaptive( - inactiveThumbColor: Color(0xFFE4E4E4), - inactiveTrackColor: Colors.white, - activeColor: Colors.white, - activeTrackColor: Color(0xFF464646), - value: model.isLightOff, - onChanged: (value) { - model.lightSwitch(value); - }, - ), - SizedBox( - height: getProportionateScreenHeight(20), - ), - Text( - 'Color', - style: Theme.of(context).textTheme.headline2, - ), - SizedBox( - height: getProportionateScreenHeight(7), - ), - InkWell( - onTap: model.showColorPanel, - child: Image.asset( - 'assets/images/color_wheel.png', - height: getProportionateScreenHeight(22), - ), - ), ], ), ), diff --git a/lib/src/screens/smart_speaker/components/body.dart b/lib/src/screens/smart_speaker/components/body.dart index 9959112..8901e30 100644 --- a/lib/src/screens/smart_speaker/components/body.dart +++ b/lib/src/screens/smart_speaker/components/body.dart @@ -1,11 +1,298 @@ -import 'package:domus/src/screens/smart_speaker/components/connect_speaker.dart'; +import 'package:domus/config/size_config.dart'; +import 'package:domus/view/smart_speaker_view_model.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:sleek_circular_slider/sleek_circular_slider.dart'; class Body extends StatelessWidget { - const Body({Key? key}) : super(key: key); + final SmartSpeakerViewModel model; + const Body({Key? key, required this.model}) : super(key: key); @override Widget build(BuildContext context) { - return Center(child: ConnectSpeaker()); + return Container( + padding: EdgeInsets.symmetric(horizontal: 15, vertical: 10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + left: getProportionateScreenWidth(19), + top: getProportionateScreenHeight(5), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: getProportionateScreenHeight(40), + ), + InkWell( + onTap: () { + Navigator.of(context).pop(); + }, + child: Icon(Icons.arrow_back_outlined)), + Stack( + children: [ + Text( + 'Smart\nSpeaker', + style: Theme.of(context).textTheme.headline1!.copyWith( + fontSize: 45, + color: Color(0xFFBDBDBD).withOpacity(0.5), + ), + ), + Text( + 'Living\nRoom', + style: Theme.of(context).textTheme.headline1, + ), + ], + ), + SizedBox( + height: getProportionateScreenHeight(10), + ), + ], + ), + ), + Align( + alignment: Alignment.center, + child: SleekCircularSlider( + min: 5, + max: 40, + initialValue: 23, + appearance: CircularSliderAppearance( + size: 200, + startAngle: 250, + angleRange: 360, + customColors: CustomSliderColors( + trackColor: Color(0xFFBDBDBD), + progressBarColor: Color(0xFF464646), + // hideShadow: true, + shadowColor: Color(0xFFBDBDBD).withOpacity(0.1), + shadowMaxOpacity: 1, + shadowStep: 25, + ), + customWidths: CustomSliderWidths( + progressBarWidth: 10, + handlerSize: 10, + trackWidth: 10, + shadowWidth: 10, + ), + ), + onChange: (double value) { + // callback providing a value while its being changed (with a pan gesture) + }, + onChangeStart: (double startValue) { + // callback providing a starting value (when a pan gesture starts) + }, + onChangeEnd: (double endValue) { + // ucallback providing an ending value (when a pan gesture ends) + }, + innerWidget: (double value) { + return Padding( + padding: const EdgeInsets.all(16.0), + child: ClipRRect( + borderRadius: BorderRadius.circular(100), + child: Image.asset( + 'assets/images/stay.jpg', + //height: getProportionateScreenHeight(50), + fit: BoxFit.cover, + ), + ), + ); + }, + ), + ), + SizedBox( + height: getProportionateScreenHeight(20), + ), + Align( + alignment: Alignment.center, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + '3:15 | 4:26', + style: Theme.of(context).textTheme.headline3, + ), + SizedBox( + height: getProportionateScreenHeight(10), + ), + Text( + 'STAY', + style: Theme.of(context).textTheme.headline1, + ), + Text( + 'Justin Bieber Ft. Kid Laroi', + style: Theme.of(context).textTheme.headline4, + ), + SizedBox( + height: 15, + ), + Divider( + thickness: 2, + ), + SizedBox( + height: 10, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () {}, + child: Icon( + Icons.first_page_rounded, + size: 30, + color: Color(0xFF464646), + ), + style: ElevatedButton.styleFrom( + elevation: 0.0, + shape: CircleBorder(), + padding: EdgeInsets.all(10), + ), + ), + ElevatedButton( + onPressed: () {}, + child: Icon( + Icons.play_arrow_rounded, + size: 35, + color: Color(0xFFF2F2F2), + ), + style: ElevatedButton.styleFrom( + elevation: 0.0, + primary: Color(0xFF464646), + shape: CircleBorder(), + padding: EdgeInsets.all(8), + ), + ), + ElevatedButton( + onPressed: () {}, + child: Icon( + Icons.last_page_rounded, + size: 30, + color: Color(0xFF464646), + ), + style: ElevatedButton.styleFrom( + elevation: 0.0, + shape: CircleBorder(), + padding: EdgeInsets.all(10), + ), + ) + ], + ), + ], + ), + ), + SizedBox( + height: getProportionateScreenHeight(15), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ElevatedButton( + onPressed: () {}, + child: Icon( + Icons.playlist_play_rounded, + size: 30, + color: Color(0xFF464646), + ), + style: ElevatedButton.styleFrom( + elevation: 0.0, + shape: CircleBorder(), + padding: EdgeInsets.all(10), + ), + ), + ElevatedButton( + onPressed: () {}, + child: Icon( + Icons.shuffle_rounded, + size: 25, + color: Color(0xFF464646), + ), + style: ElevatedButton.styleFrom( + elevation: 0.0, + shape: CircleBorder(), + padding: EdgeInsets.all(10), + ), + ), + ElevatedButton( + onPressed: () {}, + child: Icon( + Icons.repeat_rounded, + size: 25, + color: Color(0xFF464646), + ), + style: ElevatedButton.styleFrom( + elevation: 0.0, + shape: CircleBorder(), + padding: EdgeInsets.all(10), + ), + ), + ElevatedButton( + onPressed: () {}, + child: Icon( + Icons.equalizer_rounded, + size: 25, + color: Color(0xFF464646), + ), + style: ElevatedButton.styleFrom( + elevation: 0.0, + shape: CircleBorder(), + padding: EdgeInsets.all(10), + ), + ), + ElevatedButton( + onPressed: () {}, + child: Icon( + Icons.favorite_rounded, + size: 25, + color: Color(0xFF464646), + ), + style: ElevatedButton.styleFrom( + elevation: 0.0, + shape: CircleBorder(), + padding: EdgeInsets.all(10), + ), + ) + ], + ), + SizedBox( + height: getProportionateScreenHeight(15), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Kakao Mini C', + style: Theme.of(context).textTheme.headline2, + ), + SizedBox( + height: 5, + ), + Text( + 'Connected', + style: Theme.of(context).textTheme.headline5, + ) + ], + ), + Switch.adaptive( + inactiveThumbColor: Color(0xFFE4E4E4), + inactiveTrackColor: Colors.white, + activeColor: Colors.white, + activeTrackColor: Color(0xFF464646), + value: model.isSpeakeron, + onChanged: (value) { + model.speakerSwitch(value); + }, + ), + ], + ), + SizedBox( + height: getProportionateScreenHeight(9), + ), + ], + ), + ); } } diff --git a/lib/src/screens/smart_speaker/components/expandable_bottom_sheet.dart b/lib/src/screens/smart_speaker/components/expandable_bottom_sheet.dart new file mode 100644 index 0000000..bcbea50 --- /dev/null +++ b/lib/src/screens/smart_speaker/components/expandable_bottom_sheet.dart @@ -0,0 +1,189 @@ +import 'package:domus/config/size_config.dart'; +import 'package:domus/view/smart_speaker_view_model.dart'; +import 'package:flutter/material.dart'; + +Widget ExpandableBottomSheet( + {required BuildContext context, required SmartSpeakerViewModel model}) { + BorderRadiusGeometry radius = BorderRadius.only( + topLeft: Radius.circular(24.0), + topRight: Radius.circular(24.0), + ); + return Container( + decoration: BoxDecoration(color: Colors.white, borderRadius: radius), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 10, + ), + Align( + alignment: Alignment.topCenter, + child: Container( + width: 35, + height: 4, + decoration: BoxDecoration( + color: Color(0xFF464646), + borderRadius: BorderRadius.all(Radius.circular(12.0))), + ), + ), + SizedBox( + height: 25, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Schedule', + style: Theme.of(context).textTheme.headline2, + ), + SizedBox( + height: 5, + ), + Text( + 'Set schedule speaker', + style: Theme.of(context).textTheme.headline5, + ) + ], + ), + Switch.adaptive( + inactiveThumbColor: Color(0xFFE4E4E4), + inactiveTrackColor: Colors.white, + activeColor: Colors.white, + activeTrackColor: Color(0xFF464646), + value: true, + onChanged: (value) {}, + ), + ], + ), + SizedBox( + height: 15, + ), + Divider( + thickness: 2, + ), + SizedBox( + height: getProportionateScreenHeight(20), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Volume', + style: Theme.of(context).textTheme.headline2, + ), + Text( + '${model.speakerVolume.toInt()}%', + style: Theme.of(context).textTheme.headline2, + ), + ], + ), + SliderTheme( + data: SliderThemeData( + trackHeight: getProportionateScreenHeight(5), + thumbColor: Color(0xFF464646), + activeTrackColor: Color(0xFF464646), + inactiveTrackColor: Colors.white, + thumbShape: RoundSliderThumbShape(enabledThumbRadius: 8)), + child: Slider( + min: 0, + max: 100, + onChanged: (val) { + model.changeSpeakerVolume(val); + }, + value: model.speakerVolume, + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Off', + style: Theme.of(context).textTheme.bodyText1, + ), + Text( + '100%', + style: Theme.of(context).textTheme.bodyText1, + ), + ], + ), + SizedBox( + height: getProportionateScreenHeight(9), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Marshell sound dock', + style: Theme.of(context).textTheme.headline2, + ), + SizedBox( + height: 5, + ), + Text( + 'on', + style: Theme.of(context).textTheme.headline5, + ) + ], + ), + Switch.adaptive( + inactiveThumbColor: Color(0xFFE4E4E4), + inactiveTrackColor: Colors.white, + activeColor: Colors.white, + activeTrackColor: Color(0xFF464646), + value: model.isSpeakeron, + onChanged: (value) { + model.speakerSwitch(value); + }, + ), + ], + ), + SizedBox( + height: getProportionateScreenHeight(9), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Bass', + style: Theme.of(context).textTheme.headline2, + ), + SizedBox( + height: 5, + ), + Text( + 'off', + style: Theme.of(context).textTheme.headline5, + ) + ], + ), + Switch.adaptive( + inactiveThumbColor: Color(0xFFE4E4E4), + inactiveTrackColor: Colors.white, + activeColor: Colors.white, + activeTrackColor: Color(0xFF464646), + value: model.isSpeakeron, + onChanged: (value) { + model.speakerSwitch(value); + }, + ), + ], + ), + SizedBox( + height: getProportionateScreenHeight(9), + ), + ], + ), + ), + ); +} diff --git a/lib/src/screens/smart_speaker/smart_speaker.dart b/lib/src/screens/smart_speaker/smart_speaker.dart index 0755364..d6bb624 100644 --- a/lib/src/screens/smart_speaker/smart_speaker.dart +++ b/lib/src/screens/smart_speaker/smart_speaker.dart @@ -1,5 +1,10 @@ +import 'package:domus/config/size_config.dart'; +import 'package:domus/provider/base_view.dart'; +import 'package:domus/view/smart_speaker_view_model.dart'; import 'package:flutter/material.dart'; +import 'package:sliding_up_panel/sliding_up_panel.dart'; import 'components/body.dart'; +import 'components/expandable_bottom_sheet.dart'; class SmartSpeaker extends StatelessWidget { static String routeName = 'smart-speaker'; @@ -7,9 +12,24 @@ class SmartSpeaker extends StatelessWidget { @override Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Color(0xFFF2F2F2), - body: Body(), - ); + return BaseView( + onModelReady: (model) => {}, + builder: (context, model, child) { + return Material( + child: SlidingUpPanel( + minHeight: getProportionateScreenHeight(70), + controller: model.pc, + backdropEnabled: true, + boxShadow: [], + body: Scaffold( + backgroundColor: Color(0xFFF2F2F2), + body: Body( + model: model, + ), + ), + panel: ExpandableBottomSheet(context: context, model: model), + ), + ); + }); } } diff --git a/lib/view/smart_speaker_view_model.dart b/lib/view/smart_speaker_view_model.dart new file mode 100644 index 0000000..7126f02 --- /dev/null +++ b/lib/view/smart_speaker_view_model.dart @@ -0,0 +1,18 @@ +import 'package:domus/provider/base_model.dart'; +import 'package:sliding_up_panel/sliding_up_panel.dart'; + +class SmartSpeakerViewModel extends BaseModel { + PanelController pc = new PanelController(); + bool isSpeakeron = true; + double speakerVolume = 65; + + void speakerSwitch(bool value) { + isSpeakeron = value; + notifyListeners(); + } + + void changeSpeakerVolume(double newVal) { + speakerVolume = newVal; + notifyListeners(); + } +}