diff options
Diffstat (limited to 'lib/presentation/screens/settings')
23 files changed, 3104 insertions, 0 deletions
diff --git a/lib/presentation/screens/settings/settings.dart b/lib/presentation/screens/settings/settings.dart new file mode 100644 index 0000000..aa0c150 --- /dev/null +++ b/lib/presentation/screens/settings/settings.dart @@ -0,0 +1,26 @@ +import '/export.dart'; +import 'widgets/settings_content.dart'; + +class SettingsPage extends StatelessWidget { + const SettingsPage({super.key}); + + static Page<void> page() => const MaterialPage<void>(child: SettingsPage()); + @override + Widget build(BuildContext context) { + return const SettingsContent(); + } +} + +class SettingsContent extends StatelessWidget { + const SettingsContent({super.key}); + + @override + Widget build(BuildContext context) { + return const Stack( + children: [ + Settings(), + ], + ); + } +} + diff --git a/lib/presentation/screens/settings/settings_screens/audio_settings/audio_settings_screen.dart b/lib/presentation/screens/settings/settings_screens/audio_settings/audio_settings_screen.dart new file mode 100644 index 0000000..3c3508e --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/audio_settings/audio_settings_screen.dart @@ -0,0 +1,30 @@ +import 'package:flutter_ics_homescreen/export.dart'; + +import 'widget/audio_content.dart'; + + +class AudioSettingsPage extends ConsumerWidget { + const AudioSettingsPage({super.key}); + + static Page<void> page() => + const MaterialPage<void>(child: AudioSettingsPage()); + @override + Widget build(BuildContext context, WidgetRef ref) { + return Scaffold( + body: Column( + children: [ + CommonTitle( + title: 'Audio Settings', + hasBackButton: true, + onPressed: () { + context.flow<AppState>().update((state) => AppState.settings); + }, + ), + const Expanded( + child: AudioContent()), + ], + ), + ); + } +} + diff --git a/lib/presentation/screens/settings/settings_screens/audio_settings/widget/audio_content.dart b/lib/presentation/screens/settings/settings_screens/audio_settings/widget/audio_content.dart new file mode 100644 index 0000000..8fb0437 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/audio_settings/widget/audio_content.dart @@ -0,0 +1,41 @@ +import '../../../../../../export.dart'; +import 'slider_widgets.dart'; + +class AudioContent extends ConsumerWidget { + const AudioContent({ + super.key, + }); + + @override + Widget build(BuildContext context, WidgetRef ref) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 50, horizontal: 144), + child: Column( + children: [ + const Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CustomTrebleSlider(), + CustomBassSlider(), + CustomRearFrontSlider(), + ], + ), + ), + Padding( + padding: const EdgeInsets.only(bottom: 150), + child: GenericButton( + heigth: 130, + width: 420, + text: 'Reset to Default', + onTap: () { + ref.read(audioStateProvider.notifier).resetToDefaults(); + }, + ), + + ), + ], + ), + ); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/audio_settings/widget/slider_widgets.dart b/lib/presentation/screens/settings/settings_screens/audio_settings/widget/slider_widgets.dart new file mode 100644 index 0000000..973c9bf --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/audio_settings/widget/slider_widgets.dart @@ -0,0 +1,603 @@ +import 'package:flutter_ics_homescreen/export.dart'; +import 'package:flutter_ics_homescreen/presentation/custom_icons/custom_icons.dart'; + +class CustomTrebleSlider extends ConsumerStatefulWidget { + const CustomTrebleSlider({ + super.key, + }); + + @override + CustomTrebleSliderState createState() => CustomTrebleSliderState(); +} + +class CustomTrebleSliderState extends ConsumerState<CustomTrebleSlider> { + bool isPressed = false; + void _increase() { + setState(() { + if (_currentVal < 10) { + _currentVal++; + ref.read(audioStateProvider.notifier).setTreble(_currentVal); + } + }); + } + + void _dercrease() { + setState(() { + if (_currentVal > 0) { + _currentVal--; + ref.read(audioStateProvider.notifier).setTreble(_currentVal); + } + }); + } + + double _currentVal = 5; + @override + Widget build(BuildContext context) { + final trebleValue = + ref.watch(audioStateProvider.select((audio) => audio.treble)); + return Column( + //crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Padding( + padding: EdgeInsets.symmetric(vertical: 8), + child: Text( + 'Treble', + style: TextStyle(fontSize: 40), + ), + ), + Container( + width: 792, + height: 160, + decoration: const ShapeDecoration( + gradient: LinearGradient( + colors: <Color>[ + AGLDemoColors.neonBlueColor, + AGLDemoColors.resolutionBlueColor, + Color.fromARGB(127, 20, 31, 100), + Color(0xFF2962FF) + ], + stops: [0, 0, 1, 1], + ), + shape: StadiumBorder( + side: BorderSide( + color: Color(0xFF5477D4), + width: 1, + )), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 40), + child: InkWell( + onTap: () { + _dercrease(); + }, + child: const Icon( + Icons.remove, + color: AGLDemoColors.periwinkleColor, + size: 48, + ), + ), + ), + SizedBox( + width: 584, + child: SliderTheme( + data: SliderThemeData( + showValueIndicator: ShowValueIndicator.always, + trackShape: CustomRoundedRectSliderTrackShape( + silderVal: trebleValue), + activeTickMarkColor: Colors.transparent, + inactiveTickMarkColor: Colors.transparent, + inactiveTrackColor: AGLDemoColors.backgroundInsetColor, + thumbShape: PolygonSliderThumb( + sliderValue: 3, thumbRadius: 23, isPressed: isPressed), + trackHeight: 16, + ), + child: Slider( + divisions: 10, + min: 0, + max: 10, + value: trebleValue, + onChanged: (newValue) { + ref.read(audioStateProvider.notifier).setTreble(newValue); + _currentVal = newValue; + }, + onChangeEnd: (value) { + setState(() { + isPressed = false; + }); + }, + onChangeStart: (value) { + setState(() { + isPressed = true; + }); + }, + ), + ), + ), + + Padding( + padding: const EdgeInsets.only( + right: 40, + ), + child: InkWell( + onTap: () { + _increase(); + }, + child: const Icon( + Icons.add, + color: AGLDemoColors.periwinkleColor, + size: 48, + )), + ), + ], + ), + ), + ], + ); + } +} + +class CustomBassSlider extends ConsumerStatefulWidget { + const CustomBassSlider({ + super.key, + }); + + @override + CustomBassSliderState createState() => CustomBassSliderState(); +} + +class CustomBassSliderState extends ConsumerState<CustomBassSlider> { + bool isPressed = false; + + void _increase() { + setState(() { + if (_currentVal < 10) { + _currentVal++; + ref.read(audioStateProvider.notifier).setBass(_currentVal); + } + }); + } + + void _dercrease() { + setState(() { + if (_currentVal > 0) { + _currentVal--; + ref.read(audioStateProvider.notifier).setBass(_currentVal); + } + }); + } + + double _currentVal = 5; + @override + Widget build(BuildContext context) { + final bassValue = + ref.watch(audioStateProvider.select((audio) => audio.bass)); + + return Column( + //crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Padding( + padding: EdgeInsets.symmetric(vertical: 8), + child: Text( + 'Bass', + style: TextStyle(fontSize: 40), + ), + ), + Container( + width: 792, + height: 160, + decoration: const ShapeDecoration( + gradient: LinearGradient( + colors: <Color>[ + AGLDemoColors.neonBlueColor, + AGLDemoColors.resolutionBlueColor, + Color.fromARGB(127, 20, 31, 100), + Color(0xFF2962FF) + ], + stops: [0, 0, 1, 1], + ), + shape: StadiumBorder( + side: BorderSide( + color: Color(0xFF5477D4), + width: 1, + )), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 40), + child: InkWell( + onTap: () { + _dercrease(); + }, + child: const Icon( + Icons.remove, + color: AGLDemoColors.periwinkleColor, + size: 48, + )), + ), + SizedBox( + width: 584, + child: SliderTheme( + data: SliderThemeData( + showValueIndicator: ShowValueIndicator.always, + trackShape: + CustomRoundedRectSliderTrackShape(silderVal: bassValue), + activeTickMarkColor: Colors.transparent, + inactiveTickMarkColor: Colors.transparent, + inactiveTrackColor: AGLDemoColors.backgroundInsetColor, + thumbShape: PolygonSliderThumb( + sliderValue: 3, thumbRadius: 23, isPressed: isPressed), + trackHeight: 16, + ), + child: Slider( + divisions: 10, + min: 0, + max: 10, + value: bassValue, + onChanged: (newValue) { + ref.read(audioStateProvider.notifier).setBass(newValue); + _currentVal = newValue; + }, + onChangeEnd: (value) { + setState(() { + isPressed = false; + }); + }, + onChangeStart: (value) { + setState(() { + isPressed = true; + }); + }, + ), + ), + ), + Padding( + padding: const EdgeInsets.only(right: 40), + child: InkWell( + onTap: () { + _increase(); + }, + child: const Icon( + Icons.add, + color: AGLDemoColors.periwinkleColor, + size: 48, + )), + ), + ], + ), + ), + ], + ); + } +} + +class CustomRearFrontSlider extends ConsumerStatefulWidget { + const CustomRearFrontSlider({ + super.key, + }); + + @override + CustomRearFrontState createState() => CustomRearFrontState(); +} + +class CustomRearFrontState extends ConsumerState<CustomRearFrontSlider> { + bool isPressed = false; + + void _increase() { + setState(() { + if (_currentVal < 10) { + _currentVal++; + ref.read(audioStateProvider.notifier).setRearFront(_currentVal); + } + }); + } + + void _dercrease() { + setState(() { + if (_currentVal > 0) { + _currentVal--; + ref.read(audioStateProvider.notifier).setRearFront(_currentVal); + } + }); + } + + double _currentVal = 5; + @override + Widget build(BuildContext context) { + final rearFrontValue = + ref.watch(audioStateProvider.select((audio) => audio.rearFront)); + return Column( + //crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Padding( + padding: EdgeInsets.symmetric(vertical: 8), + child: Text( + 'Rear/Front', + style: TextStyle(fontSize: 40), + ), + ), + Container( + width: 792, + height: 160, + decoration: const ShapeDecoration( + gradient: LinearGradient( + colors: <Color>[ + AGLDemoColors.neonBlueColor, + AGLDemoColors.resolutionBlueColor, + Color.fromARGB(127, 20, 31, 100), + Color(0xFF2962FF) + ], + stops: [0, 0, 1, 1], + ), + shape: StadiumBorder( + side: BorderSide( + color: Color(0xFF5477D4), + width: 1, + )), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 40), + child: InkWell( + onTap: () { + _dercrease(); + }, + child: const Icon( + CustomIcons.slider_rear, + color: AGLDemoColors.periwinkleColor, + size: 48, + )), + ), + SizedBox( + width: 584, + child: SliderTheme( + data: SliderThemeData( + showValueIndicator: ShowValueIndicator.always, + trackShape: CustomRoundedRectSliderTrackShape( + silderVal: rearFrontValue, isFrontRear: true), + activeTickMarkColor: Colors.transparent, + inactiveTickMarkColor: Colors.transparent, + inactiveTrackColor: AGLDemoColors.backgroundInsetColor, + thumbShape: PolygonSliderThumb( + sliderValue: 3, thumbRadius: 23, isPressed: isPressed), + trackHeight: 16, + ), + child: Slider( + divisions: 10, + min: 0, + max: 10, + value: rearFrontValue, + onChanged: (newValue) { + ref + .read(audioStateProvider.notifier) + .setRearFront(newValue); + _currentVal = newValue; + }, + onChangeEnd: (value) { + setState(() { + isPressed = false; + }); + }, + onChangeStart: (value) { + setState(() { + isPressed = true; + }); + }, + ), + ), + ), + Padding( + padding: const EdgeInsets.only(right: 40), + child: InkWell( + onTap: () { + _increase(); + }, + child: const Icon( + CustomIcons.slider_front, + color: AGLDemoColors.periwinkleColor, + size: 48, + )), + ), + ], + ), + ), + ], + ); + } +} + +class PolygonSliderThumb extends SliderComponentShape { + final double thumbRadius; + final double sliderValue; + final bool isPressed; + const PolygonSliderThumb( + {required this.thumbRadius, + required this.sliderValue, + this.isPressed = false}); + + @override + Size getPreferredSize(bool isEnabled, bool isDiscrete) { + return Size.fromRadius(thumbRadius); + } + + @override + void paint( + PaintingContext context, + Offset center, { + required Animation<double> activationAnimation, + required Animation<double> enableAnimation, + required bool isDiscrete, + required TextPainter labelPainter, + required RenderBox parentBox, + required SliderThemeData sliderTheme, + required TextDirection textDirection, + required double value, + required double textScaleFactor, + required Size sizeWithOverflow, + }) { + // Define the slider thumb design here + final Canvas canvas = context.canvas; + var paintStroke = Paint() + ..color = + isPressed ? AGLDemoColors.jordyBlueColor : AGLDemoColors.neonBlueColor + ..strokeWidth = 2 + ..style = PaintingStyle.stroke + ..strokeCap = StrokeCap.round; + var paintFill = Paint() + ..color = isPressed ? Colors.white : AGLDemoColors.periwinkleColor + ..strokeWidth = 2 + ..style = PaintingStyle.fill + ..strokeCap = StrokeCap.round; + var path = Path(); + path.addOval(Rect.fromCircle( + center: center, + radius: 9, + )); + canvas.drawCircle(center, isPressed ? 37 : 32, paintFill); + canvas.drawShadow(path, Colors.black26, 0.5, false); + canvas.drawCircle(center, isPressed ? 21 : 16, paintStroke); + } +} + +//TODO add border to custom track Shape +class CustomRoundedRectSliderTrackShape extends SliderTrackShape + with BaseSliderTrackShape { + final double silderVal; + final bool? isFrontRear; + + CustomRoundedRectSliderTrackShape({ + required this.silderVal, + this.isFrontRear = false, + }); + @override + void paint( + PaintingContext context, + Offset offset, { + required RenderBox parentBox, + required SliderThemeData sliderTheme, + required Animation<double> enableAnimation, + required TextDirection textDirection, + required Offset thumbCenter, + Offset? secondaryOffset, + bool isDiscrete = false, + bool isEnabled = false, + double additionalActiveTrackHeight = 2, + }) { + assert(sliderTheme.disabledActiveTrackColor != null); + assert(sliderTheme.disabledInactiveTrackColor != null); + assert(sliderTheme.activeTrackColor != null); + assert(sliderTheme.inactiveTrackColor != null); + assert(sliderTheme.thumbShape != null); + if (sliderTheme.trackHeight == null || sliderTheme.trackHeight! <= 0) { + return; + } + + final Rect trackRect = getPreferredRect( + parentBox: parentBox, + offset: offset, + sliderTheme: sliderTheme, + isEnabled: isEnabled, + isDiscrete: isDiscrete, + ); + final Radius trackRadius = Radius.circular(trackRect.height / 2); + final Radius activeTrackRadius = + Radius.circular((trackRect.height + additionalActiveTrackHeight) / 2); + final activeGradientRect = Rect.fromLTRB( + trackRect.left, + textDirection == TextDirection.ltr + ? trackRect.top - (additionalActiveTrackHeight / 2) + : trackRect.top, + thumbCenter.dx, + (textDirection == TextDirection.ltr) + ? trackRect.bottom + (additionalActiveTrackHeight / 2) + : trackRect.bottom, + ); + + LinearGradient gradient = const LinearGradient( + colors: [AGLDemoColors.jordyBlueColor, Colors.white]); + // Assign the track segment paints, which are leading: active and + // trailing: inactive. + final ColorTween activeTrackColorTween = ColorTween( + begin: sliderTheme.disabledActiveTrackColor, + end: sliderTheme.activeTrackColor); + final ColorTween inactiveTrackColorTween = ColorTween( + begin: sliderTheme.disabledInactiveTrackColor, + end: sliderTheme.inactiveTrackColor); + final Paint activePaint = Paint() + ..shader = gradient.createShader(activeGradientRect) + ..color = activeTrackColorTween.evaluate(enableAnimation)!; + final Paint inactivePaint = Paint() + ..color = inactiveTrackColorTween.evaluate(enableAnimation)!; + final Paint leftTrackPaint; + final Paint rightTrackPaint; + switch (textDirection) { + case TextDirection.ltr: + leftTrackPaint = activePaint; + rightTrackPaint = inactivePaint; + case TextDirection.rtl: + leftTrackPaint = inactivePaint; + rightTrackPaint = activePaint; + } + //center divider + final smallRect = + Rect.fromLTWH(trackRect.right / 2, trackRect.bottom / 2 + 15, 10, 40); + context.canvas.drawRRect( + RRect.fromRectAndCorners(smallRect, + topLeft: const Radius.circular(25), + topRight: const Radius.circular(25), + bottomLeft: const Radius.circular(25), + bottomRight: const Radius.circular(25)), + //silderVal > 5 ? leftTrackPaint : rightTrackPaint); + isFrontRear! + ? rightTrackPaint + : silderVal > 5 + ? leftTrackPaint + : rightTrackPaint); +//active + context.canvas.drawRRect( + RRect.fromLTRBAndCorners( + trackRect.left, + (textDirection == TextDirection.ltr) + ? trackRect.top - (additionalActiveTrackHeight / 2) + : trackRect.top, + thumbCenter.dx, + (textDirection == TextDirection.ltr) + ? trackRect.bottom + (additionalActiveTrackHeight / 2) + : trackRect.bottom, + topLeft: (textDirection == TextDirection.ltr) + ? activeTrackRadius + : trackRadius, + bottomLeft: (textDirection == TextDirection.ltr) + ? activeTrackRadius + : trackRadius, + ), + isFrontRear! ? rightTrackPaint : leftTrackPaint, + ); + //inactive + context.canvas.drawRRect( + RRect.fromLTRBAndCorners( + thumbCenter.dx, + (textDirection == TextDirection.rtl) + ? trackRect.top - (additionalActiveTrackHeight / 2) + : trackRect.top, + trackRect.right, + (textDirection == TextDirection.rtl) + ? trackRect.bottom + (additionalActiveTrackHeight / 2) + : trackRect.bottom, + topRight: (textDirection == TextDirection.rtl) + ? activeTrackRadius + : trackRadius, + bottomRight: (textDirection == TextDirection.rtl) + ? activeTrackRadius + : trackRadius, + ), + rightTrackPaint, + ); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/bluetooth/bluetooth_screen.dart b/lib/presentation/screens/settings/settings_screens/bluetooth/bluetooth_screen.dart new file mode 100644 index 0000000..fe53953 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/bluetooth/bluetooth_screen.dart @@ -0,0 +1,12 @@ +import 'package:flutter_ics_homescreen/export.dart'; +import 'widgets/bluetooth_content.dart'; + +class BluetoothPage extends ConsumerWidget { + const BluetoothPage({super.key}); + + static Page<void> page() => const MaterialPage<void>(child: BluetoothPage()); + @override + Widget build(BuildContext context, WidgetRef ref) { + return const Scaffold(body: BluetoothContent()); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/bluetooth/widgets/bluetooth.dart b/lib/presentation/screens/settings/settings_screens/bluetooth/widgets/bluetooth.dart new file mode 100644 index 0000000..39ba417 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/bluetooth/widgets/bluetooth.dart @@ -0,0 +1,12 @@ +import '../../../../../../export.dart'; + +class Bluetooth { + final Icon icon; + final String name; + final bool? isConnected; + Bluetooth({ + required this.icon, + required this.name, + this.isConnected = false, + }); +} diff --git a/lib/presentation/screens/settings/settings_screens/bluetooth/widgets/bluetooth_content.dart b/lib/presentation/screens/settings/settings_screens/bluetooth/widgets/bluetooth_content.dart new file mode 100644 index 0000000..446a3b5 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/bluetooth/widgets/bluetooth_content.dart @@ -0,0 +1,219 @@ +import 'package:flutter_ics_homescreen/presentation/custom_icons/custom_icons.dart'; + +import '../../../../../../../export.dart'; +import 'bluetooth.dart'; + +class BluetoothContent extends ConsumerStatefulWidget { + const BluetoothContent({ + super.key, + }); + + @override + BluetoothContentState createState() => BluetoothContentState(); +} + +class BluetoothContentState extends ConsumerState<BluetoothContent> { + final List<Bluetooth> btList = [ + Bluetooth( + icon: const Icon(CustomIcons.wifi_4_bar_unlocked), + name: 'bt', + isConnected: true), + Bluetooth( + icon: const Icon(CustomIcons.wifi_4_bar_locked), name: 'BT Phone 0'), + Bluetooth( + icon: const Icon(CustomIcons.wifi_3_bar_locked), name: 'BT Phone 1'), + Bluetooth( + icon: const Icon(CustomIcons.wifi_2_bar_locked), name: 'BT Phone 2'), + Bluetooth( + icon: const Icon(CustomIcons.wifi_1_bar_locked), name: 'BT Phone 1'), + ]; + bool isLoading = false; + Bluetooth currentBt = + Bluetooth(icon: const Icon(Icons.wifi), name: '22', isConnected: true); + @override + void initState() { + currentBt = btList[0]; + super.initState(); + } + + void setCurrentBt(int index) async { + if (currentBt == btList[index]) return; + isLoading = true; + setState(() { + currentBt = btList[index]; + }); + Future.delayed(const Duration(seconds: 2), () { + setState(() { + isLoading = false; + }); + }); + } + + void removeBtPair(int index) { + setState(() { + btList.removeAt(index); + }); + } + + void disconnect() { + setState(() { + currentBt = Bluetooth( + icon: const Icon( + Icons.bluetooth_disabled, + ), + name: ''); + }); + } + + @override + Widget build(BuildContext context) { + ref.watch(usersProvider.select((user) => user.selectedUser)); + + return Column( + children: [ + CommonTitle( + title: "Bluetooth", + hasBackButton: true, + onPressed: () { + context.flow<AppState>().update((state) => AppState.settings); + }, + ), + Expanded( + child: ListView.separated( + padding: const EdgeInsets.symmetric(vertical: 50, horizontal: 144), + itemCount: btList.length, + separatorBuilder: (context, index) { + return const SizedBox( + height: 8, + ); + }, + itemBuilder: (context, index) { + return Container( + height: 130, + alignment: Alignment.center, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: currentBt == btList[index] + ? [0, 0.01, 0.8] + : [0.1, 1], + colors: currentBt == btList[index] + ? <Color>[ + Colors.white, + Colors.blue, + const Color.fromARGB(16, 41, 98, 255) + ] + : <Color>[Colors.black, Colors.black12]), + ), + child: InkWell( + onTap: () { + setCurrentBt(index); + }, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 17, horizontal: 24), + child: Row(children: [ + Expanded( + child: Text( + btList[index].name, + //style: Theme.of(context).textTheme.titleMedium, + style: TextStyle( + color: currentBt == btList[index] + ? Colors.white + : AGLDemoColors.periwinkleColor, + fontSize: 40), + ), + ), + currentBt == btList[index] + ? Row( + mainAxisSize: MainAxisSize.min, + children: [ + isLoading + ? const Padding( + padding: EdgeInsets.only(right: 15.0), + child: Text( + 'Connecting...', + style: TextStyle(fontSize: 26), + ), + ) + : Padding( + padding: + const EdgeInsets.only(right: 8.0), + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: + const Color(0xFF1C2D92), + side: const BorderSide( + color: Color(0xFF285DF4), + width: 2), + ), + child: const Padding( + padding: EdgeInsets.all(18), + child: Text( + 'Disconnect', + style: TextStyle( + color: Color(0xFFC1D8FF), + fontSize: 26, + ), + ), + ), + onPressed: () { + disconnect(); + }, + ), + ), + isLoading + ? const SizedBox( + width: 48, + height: 48, + child: CircularProgressIndicator( + strokeWidth: 3, + )) + : IconButton( + padding: EdgeInsets.zero, + onPressed: () { + removeBtPair(index); + }, + icon: const Icon( + Icons.close, + color: AGLDemoColors.periwinkleColor, + size: 48, + ), + ), + ], + ) + : IconButton( + padding: EdgeInsets.zero, + onPressed: () { + removeBtPair(index); + }, + icon: const Icon( + Icons.close, + color: AGLDemoColors.periwinkleColor, + size: 48, + ), + ), + ]), + ), + ), + ); + }, + ), + ), + Padding( + padding: const EdgeInsets.only(bottom: 150.0), + child: GenericButton( + heigth: 130, + width: 501, + text: 'Scan for New Device', + onTap: () {}, + ), + ), + const SizedBox( + height: 100, + ) + ], + ); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/date_time/date/date_screen.dart b/lib/presentation/screens/settings/settings_screens/date_time/date/date_screen.dart new file mode 100644 index 0000000..6802ed0 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/date_time/date/date_screen.dart @@ -0,0 +1,218 @@ +import 'package:flutter_ics_homescreen/export.dart'; +import 'package:calendar_date_picker2/calendar_date_picker2.dart'; +import 'package:intl/intl.dart'; + +class DatePage extends ConsumerWidget { + const DatePage({super.key}); + static Page<void> page() => const MaterialPage<void>(child: DatePage()); + + @override + Widget build(BuildContext context, WidgetRef ref) { + return Scaffold( + body: Column(children: [ + CommonTitle( + title: 'Date', + hasBackButton: true, + onPressed: () { + context.flow<AppState>().update((state) => AppState.dateTime); + }, + ), + const Expanded( + child: Padding( + padding: EdgeInsets.symmetric(vertical: 20, horizontal: 144), + child: SingleChildScrollView(child: DateScreenWidget())), + ), + ]), + ); + } +} + +class DateScreenWidget extends ConsumerStatefulWidget { + const DateScreenWidget({super.key}); + Page<void> page() => const MaterialPage<void>(child: DateScreenWidget()); + + @override + DateScreenWidgetState createState() => DateScreenWidgetState(); +} + +class DateScreenWidgetState extends ConsumerState<DateScreenWidget> { + late String selectedDate; + + onPressed({required String type}) { + if (type == "confirm") { + ref.read(dateTimeStateProvider.notifier).setDate(selectedDate); + context.flow<AppState>().update((state) => AppState.dateTime); + } else if (type == "cancel") { + context.flow<AppState>().update((state) => AppState.dateTime); + } + } + + @override + void initState() { + selectedDate = ref.read(dateTimeStateProvider).date; + + super.initState(); + } + + @override + Widget build(BuildContext context) { + Size size = MediaQuery.sizeOf(context); + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + CalendarDatePicker2( + config: CalendarDatePicker2Config( + calendarType: CalendarDatePicker2Type.single, + dayBuilder: ( + {required date, + decoration, + isDisabled, + isSelected, + isToday, + textStyle}) { + Widget? dayWidget; + dayWidget = Container( + decoration: decoration, + child: Center( + child: Stack( + alignment: AlignmentDirectional.center, + children: [ + Text( + MaterialLocalizations.of(context) + .formatDecimal(date.day), + style: textStyle, + ), + ], + ), + ), + ); + + return dayWidget; + }, + dayTextStyle: const TextStyle( + color: AGLDemoColors.periwinkleColor, fontSize: 40), + selectedDayHighlightColor: AGLDemoColors.neonBlueColor, + controlsTextStyle: const TextStyle( + color: AGLDemoColors.periwinkleColor, fontSize: 40), + weekdayLabelTextStyle: const TextStyle( + color: AGLDemoColors.periwinkleColor, fontSize: 40), + controlsHeight: 40, + dayTextStylePredicate: ({required date}) { + return const TextStyle( + color: AGLDemoColors.periwinkleColor, fontSize: 40); + }, + selectedDayTextStyle: + const TextStyle(color: Colors.white, fontSize: 40)), + value: selectedDate == "mm/dd/yyyy" + ? [] + : [DateFormat().add_yMMMMd().parse(selectedDate)], + onValueChanged: (dates) { + setState(() { + selectedDate = DateFormat().add_yMMMMd().format(dates.first!); + }); + }, + ), + const SizedBox( + height: 120, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Material( + color: Colors.transparent, + child: InkWell( + onHighlightChanged: (value) { + // setState(() { + // isCancelButtonHighlighted = value; + // }); + }, + onTap: () { + onPressed(type: "cancel"); + + // onTap(type: "cancel"); + }, + child: Container( + width: size.width / 3.2, + alignment: Alignment.center, + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.7), + blurRadius: 1.5, + offset: const Offset(1, 2)) + ], + gradient: LinearGradient(colors: [ + AGLDemoColors.resolutionBlueColor, + AGLDemoColors.neonBlueColor.withOpacity(0.15), + ]), + borderRadius: BorderRadius.circular(3), + border: Border.all( + color: + AGLDemoColors.neonBlueColor.withOpacity(0.20))), + child: const Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: Text( + "Cancel", + style: TextStyle( + color: AGLDemoColors.periwinkleColor, + fontWeight: FontWeight.w600, + fontSize: 40, + letterSpacing: 0.4), + ), + ), + ), + ), + ), + const SizedBox( + width: 10, + ), + Material( + color: Colors.transparent, + child: InkWell( + onHighlightChanged: (value) { + // setState(() { + // isCancelButtonHighlighted = value; + // }); + }, + onTap: () { + onPressed(type: "confirm"); + // onTap(type: "cancel"); + }, + child: Container( + width: MediaQuery.sizeOf(context).width / 3.2, + alignment: Alignment.center, + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.7), + blurRadius: 1.5, + offset: const Offset(1, 2)) + ], + gradient: LinearGradient(colors: [ + AGLDemoColors.resolutionBlueColor, + AGLDemoColors.neonBlueColor.withOpacity(0.15), + ]), + borderRadius: BorderRadius.circular(3), + border: Border.all( + color: + AGLDemoColors.neonBlueColor.withOpacity(0.20))), + child: const Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: Text( + "Confirm", + style: TextStyle( + color: AGLDemoColors.periwinkleColor, + fontWeight: FontWeight.w600, + fontSize: 40, + letterSpacing: 0.4), + ), + ), + ), + ), + ), + ], + ), + ], + ); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/date_time/date_time_screen.dart b/lib/presentation/screens/settings/settings_screens/date_time/date_time_screen.dart new file mode 100644 index 0000000..2365ecc --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/date_time/date_time_screen.dart @@ -0,0 +1,54 @@ +import 'package:flutter_ics_homescreen/export.dart'; + +class DateTimePage extends ConsumerWidget { + const DateTimePage({super.key}); + + static Page<void> page() => const MaterialPage<void>(child: DateTimePage()); + @override + Widget build(BuildContext context, WidgetRef ref) { + final dateTime = ref.watch(dateTimeStateProvider.select((val) => val)); + + return Scaffold( + body: Column( + children: [ + CommonTitle( + title: 'Date & Time', + hasBackButton: true, + onPressed: () { + context.flow<AppState>().update((state) => AppState.settings); + }, + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 144), + child: ListView( + children: [ + UnitsTile( + image: "assets/Calendar.svg", + title: 'Date', + unitName: dateTime.date, + hasSwich: false, + voidCallback: () async { + context + .flow<AppState>() + .update((next) => AppState.date); + }), + UnitsTile( + image: "assets/Time.svg", + title: 'Time', + unitName: dateTime.time, + hasSwich: true, + voidCallback: () { + context + .flow<AppState>() + .update((next) => AppState.time); + }), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/date_time/time/time_screen.dart b/lib/presentation/screens/settings/settings_screens/date_time/time/time_screen.dart new file mode 100644 index 0000000..61131b5 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/date_time/time/time_screen.dart @@ -0,0 +1,426 @@ +import 'package:flutter_ics_homescreen/export.dart'; +import 'package:flutter/services.dart'; +import 'package:intl/intl.dart'; + +class TimePage extends ConsumerWidget { + const TimePage({super.key}); + static Page<void> page() => const MaterialPage<void>(child: TimePage()); + + @override + Widget build(BuildContext context, WidgetRef ref) { + return Scaffold( + body: Column(children: [ + CommonTitle( + title: 'Time', + hasBackButton: true, + onPressed: () { + context.flow<AppState>().update((state) => AppState.dateTime); + }, + ), + const Expanded( + child: Padding( + padding: EdgeInsets.symmetric(vertical: 20, horizontal: 144), + child: SingleChildScrollView(child: TimeScreenWidget())), + ), + ]), + ); + } +} + +class TimeScreenWidget extends ConsumerStatefulWidget { + const TimeScreenWidget({super.key}); + Page<void> page() => const MaterialPage<void>(child: TimeScreenWidget()); + + @override + TimeScreenWidgetState createState() => TimeScreenWidgetState(); +} + +class TimeScreenWidgetState extends ConsumerState<TimeScreenWidget> { + late int selectedTimeHour; + late int selectedTimeMinute; + String selectedMeridien = "AM"; + + TextEditingController hourController = TextEditingController(); + TextEditingController minuteController = TextEditingController(); + + onPressed({required String type}) { + if (type == "confirm") { + ref.read(dateTimeStateProvider.notifier).setTime( + "${hourController.text}:${minuteController.text} $selectedMeridien"); + context.flow<AppState>().update((state) => AppState.dateTime); + } else if (type == "cancel") { + context.flow<AppState>().update((state) => AppState.dateTime); + } + } + + @override + void initState() { + String time = ref.read(dateTimeStateProvider).time; + if (time == "hh:mm a") { + time = DateFormat('hh:mm a').format(DateTime.now()); + } + List<String> split = time.split(":"); + selectedTimeHour = int.parse(split[0]); + List<String> splitMeridian = split[1].split(" "); + + selectedTimeMinute = int.parse(splitMeridian[0]); + + setState(() { + selectedMeridien = splitMeridian[1]; + hourController.text = selectedTimeHour.toString(); + minuteController.text = selectedTimeMinute.toString(); + }); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + Size size = MediaQuery.sizeOf(context); + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox( + height: 60, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + TimeTextField( + controller: hourController, + type: "hour", + ), + const Padding( + padding: EdgeInsets.all(15), + child: Text( + ":", + style: TextStyle( + color: AGLDemoColors.periwinkleColor, fontSize: 44), + ), + ), + TimeTextField( + controller: minuteController, + type: "minute", + ), + ], + ), + const SizedBox( + height: 50, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(30), + bottomLeft: Radius.circular(30), + ), + border: Border.all(color: AGLDemoColors.periwinkleColor), + color: selectedMeridien == "AM" + ? AGLDemoColors.neonBlueColor + : Colors.transparent), + child: Material( + color: Colors.transparent, + child: InkWell( + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(30), + bottomLeft: Radius.circular(30), + ), + onTap: () { + setState(() { + selectedMeridien = "AM"; + }); + }, + child: Padding( + padding: const EdgeInsets.only( + top: 17, bottom: 17, right: 30, left: 25), + child: Row( + children: [ + selectedMeridien == "AM" + ? const Icon( + Icons.check, + size: 48, + color: Colors.white, + ) + : const SizedBox( + width: 48, + height: 48, + ), + const SizedBox( + width: 3, + ), + Text( + "AM", + style: TextStyle( + color: selectedMeridien == "AM" + ? Colors.white + : AGLDemoColors.periwinkleColor, + fontSize: 40), + ) + ], + ), + ), + ), + ), + ), + Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.only( + topRight: Radius.circular(30), + bottomRight: Radius.circular(30), + ), + border: Border.all(color: AGLDemoColors.periwinkleColor), + color: selectedMeridien == "PM" + ? AGLDemoColors.neonBlueColor + : Colors.transparent), + child: Material( + color: Colors.transparent, + child: InkWell( + borderRadius: const BorderRadius.only( + topRight: Radius.circular(30), + bottomRight: Radius.circular(30), + ), + onTap: () { + setState(() { + selectedMeridien = "PM"; + }); + }, + child: Padding( + padding: const EdgeInsets.only( + top: 17, bottom: 17, right: 30, left: 25), + child: Row( + children: [ + selectedMeridien == "PM" + ? const Icon( + Icons.check, + size: 48, + color: Colors.white, + ) + : const SizedBox( + width: 48, + height: 48, + ), + const SizedBox( + width: 3, + ), + Text( + "PM", + style: TextStyle( + color: selectedMeridien == "PM" + ? Colors.white + : AGLDemoColors.periwinkleColor, + fontSize: 40), + ), + ], + ), + ), + ), + ), + ), + ], + ), + const SizedBox( + height: 200, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Material( + color: Colors.transparent, + child: InkWell( + onHighlightChanged: (value) { + // setState(() { + // isCancelButtonHighlighted = value; + // }); + }, + onTap: () { + onPressed(type: "cancel"); + + // onTap(type: "cancel"); + }, + child: Container( + width: size.width / 3.2, + alignment: Alignment.center, + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.7), + blurRadius: 1.5, + offset: const Offset(1, 2)) + ], + gradient: LinearGradient(colors: [ + AGLDemoColors.resolutionBlueColor, + AGLDemoColors.neonBlueColor.withOpacity(0.15), + ]), + borderRadius: BorderRadius.circular(3), + border: Border.all( + color: + AGLDemoColors.neonBlueColor.withOpacity(0.20))), + child: const Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Text( + "Cancel", + style: TextStyle( + color: AGLDemoColors.periwinkleColor, + fontWeight: FontWeight.w600, + fontSize: 40, + letterSpacing: 0.4), + ), + ), + ), + ), + ), + const SizedBox( + width: 10, + ), + Material( + color: Colors.transparent, + child: InkWell( + onHighlightChanged: (value) { + // setState(() { + // isCancelButtonHighlighted = value; + // }); + }, + onTap: () { + onPressed(type: "confirm"); + // onTap(type: "cancel"); + }, + child: Container( + width: MediaQuery.sizeOf(context).width / 3.2, + alignment: Alignment.center, + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.7), + blurRadius: 1.5, + offset: const Offset(1, 2)) + ], + gradient: LinearGradient(colors: [ + AGLDemoColors.resolutionBlueColor, + AGLDemoColors.neonBlueColor.withOpacity(0.15), + ]), + borderRadius: BorderRadius.circular(3), + border: Border.all( + color: + AGLDemoColors.neonBlueColor.withOpacity(0.20))), + child: const Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Text( + "Confirm", + style: TextStyle( + color: AGLDemoColors.periwinkleColor, + fontWeight: FontWeight.w600, + fontSize: 40, + letterSpacing: 0.4), + ), + ), + ), + ), + ), + ], + ), + ], + ); + } +} + +class TimeTextField extends StatefulWidget { + const TimeTextField( + {super.key, required this.controller, required this.type}); + final TextEditingController controller; + final String type; + + @override + State<TimeTextField> createState() => _TimeTextFieldState(); +} + +class _TimeTextFieldState extends State<TimeTextField> { + TextEditingController controller = TextEditingController(); + @override + void initState() { + super.initState(); + controller = widget.controller; + } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + + onKeyBoardEvent(RawKeyEvent event) { + if (event.isKeyPressed(LogicalKeyboardKey.arrowUp)) { + if (controller.text != "") { + int value = int.tryParse(controller.text) ?? 0; + if (widget.type == "hour") { + if (value > 11) { + controller.text = "12"; + } else { + controller.text = (value + 1).toString(); + } + } else if (widget.type == "minute") { + if (value > 58) { + controller.text = "59"; + } else { + controller.text = (value + 1).toString(); + } + } + return KeyEventResult.handled; + } else { + controller.text = "0"; + return KeyEventResult.handled; + } + } else if (event.isKeyPressed(LogicalKeyboardKey.arrowDown)) { + if (controller.text.isNotEmpty) { + int value = int.tryParse(controller.text) ?? 0; + if (value < 1) { + controller.text = "0"; + } else { + controller.text = (value - 1).toString(); + } + return KeyEventResult.handled; + } else { + controller.text = "0"; + return KeyEventResult.handled; + } + } + return KeyEventResult.ignored; + } + + @override + Widget build(BuildContext context) { + return SizedBox( + width: 185, + child: RawKeyboardListener( + focusNode: FocusNode(onKey: (node, event) { + return onKeyBoardEvent(event); + }), + child: TextField( + style: const TextStyle(color: Colors.white, fontSize: 40), + decoration: InputDecoration( + contentPadding: const EdgeInsets.symmetric(vertical: 23), + filled: true, + fillColor: AGLDemoColors.blueGlowFillColor.withOpacity(0.1)), + controller: controller, + textAlign: TextAlign.center, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + onChanged: (value) { + if (value.isNotEmpty) { + if (widget.type == "hour") { + if (int.parse(value) > 12) { + widget.controller.text = '12'; + } + } else if (widget.type == "minute") { + if (int.parse(value) > 59) { + widget.controller.text = '59'; + } + } + } + }, + ), + )); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/profiles/profiles_screen.dart b/lib/presentation/screens/settings/settings_screens/profiles/profiles_screen.dart new file mode 100644 index 0000000..cd831b1 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/profiles/profiles_screen.dart @@ -0,0 +1,20 @@ +import 'package:flutter_ics_homescreen/export.dart'; + +import 'widgets/profiles_content.dart'; + +class ProfilesPage extends StatelessWidget { + const ProfilesPage({super.key}); + + static Page<void> page() => const MaterialPage<void>(child: ProfilesPage()); + @override + Widget build(BuildContext context) { + return const Scaffold( + body: Stack( + children: [ + ProfilesContent(), + ], + ), + ); + } +} + diff --git a/lib/presentation/screens/settings/settings_screens/profiles/widgets/new_profile_screen.dart b/lib/presentation/screens/settings/settings_screens/profiles/widgets/new_profile_screen.dart new file mode 100644 index 0000000..0cf1ddb --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/profiles/widgets/new_profile_screen.dart @@ -0,0 +1,252 @@ +import 'package:new_virtual_keyboard/virtual_keyboard.dart'; +import 'package:flutter_ics_homescreen/export.dart'; + +class NewProfilePage extends ConsumerStatefulWidget { + const NewProfilePage({super.key}); + + static Page<void> page() => const MaterialPage<void>(child: NewProfilePage()); + + @override + NewProfilePageState createState() => NewProfilePageState(); +} + +class NewProfilePageState extends ConsumerState<NewProfilePage> { + final _controller = TextEditingController(); + final _formKey = GlobalKey<FormState>(); + bool shiftEnabled = false; + + int chars = 0; + @override + void initState() { + super.initState(); + } + + _onKeyPress(VirtualKeyboardKey key) { + String text = _controller.text; + if (key.keyType == VirtualKeyboardKeyType.String) { + text = text + (shiftEnabled ? key.capsText : key.text)!; + } else if (key.keyType == VirtualKeyboardKeyType.Action) { + switch (key.action) { + case VirtualKeyboardKeyAction.Backspace: + if (text.isEmpty) return; + text = text.substring(0, text.length - 1); + break; + case VirtualKeyboardKeyAction.Return: + text = '$text\n'; + break; + case VirtualKeyboardKeyAction.Space: + text = text + key.text!; + break; + case VirtualKeyboardKeyAction.Shift: + shiftEnabled = !shiftEnabled; + break; + default: + } + } + +// Update the screen + if (text.length >= 25) { + _controller.text = text.substring(0, 25); + } else { + _controller.text = text; + } + + updateMaxChar(_controller.text.length); + } + + void showKeyboard() { + var ctx = homeScaffoldKey.currentContext; + showModalBottomSheet( + elevation: 0.0, + backgroundColor: Colors.transparent, + barrierColor: Colors.transparent, + context: ctx!, + builder: (ctx) { + return Container( + height: 479, + width: 1080, + decoration: const BoxDecoration( + color: AGLDemoColors.resolutionBlueColor, + border: Border( + top: BorderSide( + color: Color(0xFF295EF7), + width: 1, + )), + ), + child: VirtualKeyboard( + height: 478, + textColor: AGLDemoColors.periwinkleColor, + fontSize: 40, + // [A-Z, 0-9] + type: VirtualKeyboardType.Alphanumeric, + // Callback for key press event + onKeyPress: (key) { + _onKeyPress(key); + }, + ), + ); + }, + ); + } + + @override + void didChangeDependencies() async { + Future.delayed(const Duration(seconds: 0), () { + showKeyboard(); + }); + super.didChangeDependencies(); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + void updateMaxChar(int charsCount) { + setState(() { + chars = charsCount; + }); + } + + void addUser() { + ref.read(usersProvider.notifier).addUser(_controller.text); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Form( + key: _formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CommonTitle( + title: 'New Profile', + hasBackButton: true, + onPressed: () { + context.flow<AppState>().update((state) => AppState.profiles); + }, + ), + Expanded( + child: Padding( + padding: + const EdgeInsets.symmetric(vertical: 50, horizontal: 144), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + 'Profile Name', + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(fontSize: 40), + ), + const SizedBox( + height: 20, + ), + Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: [0, 0.5, 1], + colors: <Color>[ + Colors.black12, + Colors.black, + Colors.black12 + ], + ), + ), + child: Column( + children: [ + Container( + height: 140, + padding: const EdgeInsets.only(top: 30), + child: TextFormField( + onTap: () { + showKeyboard(); + }, + controller: _controller, + autofocus: true, + maxLength: 25, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter some text'; + } + return null; + }, + //maxLengthEnforcement: MaxLengthEnforcement.none, + onChanged: (value) { + if (_controller.text.length <= 1) { + if (_formKey.currentState!.validate()) {} + _formKey.currentState!.save(); + } + updateMaxChar(_controller.text.length); + }, + decoration: const InputDecoration( + border: InputBorder.none, + counterText: '', + ), + textAlign: TextAlign.center, + textDirection: TextDirection.rtl, + style: const TextStyle(fontSize: 60), + ), + ), + Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: [0, 0.2, 0.8, 1], + colors: <Color>[ + Colors.transparent, + AGLDemoColors.neonBlueColor, + AGLDemoColors.neonBlueColor, + Colors.transparent, + ], + ), + ), + height: 2, + ) + ], + ), + ), + const SizedBox( + height: 20, + ), + Center( + child: Text('$chars/25 Characters', + style: const TextStyle(fontSize: 26)), + ), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.only(bottom: 350.0), + child: GenericButton( + heigth: 130, + width: 493, + text: 'Save Profile', + onTap: () { + if (_formKey.currentState!.validate()) { + addUser(); + context + .flow<AppState>() + .update((state) => AppState.profiles); + } + }, + ), + + ), + Padding( + padding: const EdgeInsets.only(bottom: 150.0), + child: Container(), + ), + ], + ), + ), + ); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/profiles/widgets/profiles_content.dart b/lib/presentation/screens/settings/settings_screens/profiles/widgets/profiles_content.dart new file mode 100644 index 0000000..eb89553 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/profiles/widgets/profiles_content.dart @@ -0,0 +1,125 @@ +import '../../../../../../data/models/user.dart'; +import '../../../../../../export.dart'; + +class ProfilesContent extends ConsumerStatefulWidget { + const ProfilesContent({super.key}); + + @override + ProfilesContentState createState() => ProfilesContentState(); +} + +class ProfilesContentState extends ConsumerState<ProfilesContent> { + late User currentUser; + + void setCurrentUser(String userId) { + setState(() { + ref.read(usersProvider.notifier).selectUser(userId); + }); + } + + void removeUser(String userId) { + setState(() { + ref.read(usersProvider.notifier).removeUser(userId); + }); + } + + @override + Widget build(BuildContext context) { + var users = ref.watch(usersProvider.select((users) => users)); + final currentUser = users.selectedUser; + final usersList = users.users; + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + CommonTitle( + title: "Profiles", + hasBackButton: true, + onPressed: () { + context.flow<AppState>().update((state) => AppState.settings); + }, + ), + Expanded( + child: ListView.separated( + padding: const EdgeInsets.symmetric(vertical: 50, horizontal: 144), + itemCount: usersList.length, + separatorBuilder: (context, index) { + return const SizedBox( + height: 8, + ); + }, + itemBuilder: (context, index) { + return Container( + height: 130, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: currentUser == usersList[index] + ? [0, 0.01, 0.8] + : [0.1, 1], + colors: currentUser == usersList[index] + ? <Color>[ + Colors.white, + Colors.blue, + const Color.fromARGB(16, 41, 98, 255) + ] + : <Color>[Colors.black, Colors.black12]), + ), + child: ListTile( + minVerticalPadding: 0.0, + contentPadding: const EdgeInsets.symmetric( + horizontal: 16.0, vertical: 40.0), + leading: Text(users.users[index].name, + style: const TextStyle(fontSize: 40)), + //title: Text(widget.title), + //enabled: isSwitchOn, + trailing: IconButton( + padding: EdgeInsets.zero, + onPressed: () { + removeUser(users.users[index].id); + }, + icon: const Icon( + Icons.close, + color: AGLDemoColors.periwinkleColor, + size: 48, + ), + ), + + onTap: () { + setCurrentUser(usersList[index].id); + }, + ), + ); + }, + ), + ), + Padding( + padding: const EdgeInsets.only(bottom: 150.0), + child: Column( + children: [ + GenericButton( + heigth: 122, + width: 317, + text: 'New Profile', + onTap: () { + context + .flow<AppState>() + .update((state) => AppState.newProfile); + }, + ), + + const SizedBox(height: 20), + GenericButton( + heigth: 122, + width: 412, + text: 'Reset to Default', + onTap: () {}, + ), + ], + ), + ), + ], + ); + } +} + diff --git a/lib/presentation/screens/settings/settings_screens/units/distance/distance_unit_screen.dart b/lib/presentation/screens/settings/settings_screens/units/distance/distance_unit_screen.dart new file mode 100644 index 0000000..3e9c135 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/units/distance/distance_unit_screen.dart @@ -0,0 +1,120 @@ +import 'package:flutter_ics_homescreen/export.dart'; + +class DistanceUnitPage extends ConsumerWidget { + const DistanceUnitPage({super.key}); + + static Page<void> page() => + const MaterialPage<void>(child: DistanceUnitPage()); + @override + Widget build(BuildContext context, WidgetRef ref) { + final unit = + ref.watch(unitStateProvider.select((unit) => unit.distanceUnit)); + + return Scaffold( + + body: Column( + children: [ + CommonTitle( + title: 'Distance', + hasBackButton: true, + onPressed: () { + context.flow<AppState>().update((state) => AppState.units); + }, + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 144), + child: ListView( + children: [ + Container( + height: 130, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: unit == DistanceUnit.kilometers + ? [0, 0.01, 0.8] + : [0.1, 1], + colors: unit == DistanceUnit.kilometers + ? <Color>[ + Colors.white, + Colors.blue, + const Color.fromARGB(16, 41, 98, 255) + ] + : <Color>[Colors.black, Colors.black12]), + ), + child: ListTile( + minVerticalPadding: 0.0, + contentPadding: const EdgeInsets.symmetric( + horizontal: 16.0, vertical: 40.0), + leading: Text( + 'Kilometers', + style: Theme.of(context).textTheme.titleMedium, + ), + //title: Text(widget.title), + //enabled: isSwitchOn, + trailing: unit == DistanceUnit.kilometers + ? const Icon(Icons.done, + color: AGLDemoColors.periwinkleColor, + size: 48, + ) + : null, + onTap: () { + ref + .read(unitStateProvider.notifier) + .setDistanceUnit(DistanceUnit.kilometers); + }), + ), + const SizedBox( + height: 8, + ), + Container( + height: 130, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: unit == DistanceUnit.miles + ? [0, 0.01, 0.8] + : [0.1, 1], + colors: unit == DistanceUnit.miles + ? <Color>[ + Colors.white, + Colors.blue, + const Color.fromARGB(16, 41, 98, 255) + ] + : <Color>[Colors.black, Colors.black12]), + ), + child: ListTile( + minVerticalPadding: 0.0, + contentPadding: const EdgeInsets.symmetric( + horizontal: 16.0, vertical: 40.0), + leading: Text( + 'Miles', + style: Theme.of(context).textTheme.titleMedium, + ), + //title: Text(widget.title), + //enabled: isSwitchOn, + trailing: unit == DistanceUnit.miles + ? const Icon(Icons.done, + color: AGLDemoColors.periwinkleColor, + size: 48, + ) + : null, + + onTap: () { + ref + .read(unitStateProvider.notifier) + .setDistanceUnit(DistanceUnit.miles); + }, + ), + ), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/units/temperature/temperature_unit_screen.dart b/lib/presentation/screens/settings/settings_screens/units/temperature/temperature_unit_screen.dart new file mode 100644 index 0000000..414bf32 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/units/temperature/temperature_unit_screen.dart @@ -0,0 +1,120 @@ +import 'package:flutter_ics_homescreen/export.dart'; + +class TemperatureUnitPage extends ConsumerWidget { + const TemperatureUnitPage({super.key}); + + static Page<void> page() => + const MaterialPage<void>(child: TemperatureUnitPage()); + @override + Widget build(BuildContext context, WidgetRef ref) { + final unit = + ref.watch(unitStateProvider.select((unit) => unit.temperatureUnit)); + + return Scaffold( + + body: Column( + children: [ + CommonTitle( + title: 'Temperature', + hasBackButton: true, + onPressed: () { + context.flow<AppState>().update((state) => AppState.units); + }, + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 144), + child: ListView( + children: [ + Container( + height: 130, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: unit == TemperatureUnit.celsius + ? [0, 0.01, 0.8] + : [0.1, 1], + colors: unit == TemperatureUnit.celsius + ? <Color>[ + Colors.white, + Colors.blue, + const Color.fromARGB(16, 41, 98, 255) + ] + : <Color>[Colors.black, Colors.black12]), + ), + child: ListTile( + minVerticalPadding: 0.0, + contentPadding: const EdgeInsets.symmetric( + horizontal: 16.0, vertical: 40.0), + leading: Text( + 'Celsius', + style: Theme.of(context).textTheme.titleMedium, + ), + //title: Text(widget.title), + //enabled: isSwitchOn, + trailing: unit == TemperatureUnit.celsius + ? const Icon(Icons.done, + color: AGLDemoColors.periwinkleColor, + size: 48, + ) + : null, + onTap: () { + ref + .read(unitStateProvider.notifier) + .setTemperatureUnit(TemperatureUnit.celsius); + }), + ), + const SizedBox( + height: 5, + ), + Container( + height: 130, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: unit == TemperatureUnit.fahrenheit + ? [0, 0.01, 0.8] + : [0.1, 1], + colors: unit == TemperatureUnit.fahrenheit + ? <Color>[ + Colors.white, + Colors.blue, + const Color.fromARGB(16, 41, 98, 255) + ] + : <Color>[Colors.black, Colors.black12]), + ), + child: ListTile( + minVerticalPadding: 0.0, + contentPadding: const EdgeInsets.symmetric( + horizontal: 16.0, vertical: 40.0), + leading: Text( + 'Fahrenheit', + style: Theme.of(context).textTheme.titleMedium, + ), + //title: Text(widget.title), + //enabled: isSwitchOn, + trailing: unit == TemperatureUnit.fahrenheit + ? const Icon(Icons.done, + color: AGLDemoColors.periwinkleColor, + size: 38, + ) + : null, + + onTap: () { + ref + .read(unitStateProvider.notifier) + .setTemperatureUnit(TemperatureUnit.fahrenheit); + }, + ), + ), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/units/units_screen.dart b/lib/presentation/screens/settings/settings_screens/units/units_screen.dart new file mode 100644 index 0000000..1c6e37c --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/units/units_screen.dart @@ -0,0 +1,159 @@ +import 'package:flutter_ics_homescreen/core/utils/helpers.dart'; +import 'package:flutter_ics_homescreen/export.dart'; + +class UnitsPage extends ConsumerWidget { + const UnitsPage({super.key}); + + static Page<void> page() => const MaterialPage<void>(child: UnitsPage()); + @override + Widget build(BuildContext context, WidgetRef ref) { + final unit = ref.watch(unitStateProvider.select((unit) => unit)); + + return Scaffold( + //appBar: SettingsTopBar('Units'), + + body: Column( + children: [ + CommonTitle( + title: 'Units', + hasBackButton: true, + onPressed: () { + context.flow<AppState>().update((state) => AppState.settings); + }, + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 144), + child: ListView( + children: [ + UnitsTile( + icon: Icons.calendar_month_outlined, + title: 'Distance', + unitName: unit.distanceUnit == DistanceUnit.kilometers + ? 'Kilometers' + : 'Miles', + hasSwich: false, + voidCallback: () async { + context + .flow<AppState>() + .update((next) => AppState.distanceUnit); + }), + UnitsTile( + icon: Icons.straighten, + title: 'Temperature', + unitName: unit.temperatureUnit == TemperatureUnit.celsius + ? 'Celsius' + : 'Fahrenheit', + hasSwich: true, + voidCallback: () { + context + .flow<AppState>() + .update((next) => AppState.tempUnit); + }), + ], + ), + ), + ), + ], + ), + ); + } +} + +class UnitsTile extends ConsumerStatefulWidget { + final IconData? icon; + final String title; + final String unitName; + final bool hasSwich; + final VoidCallback voidCallback; + final String? image; + const UnitsTile({ + Key? key, + this.icon, + required this.title, + required this.unitName, + required this.hasSwich, + required this.voidCallback, + this.image, + }) : super(key: key); + + @override + UnitsTileState createState() => UnitsTileState(); +} + +class UnitsTileState extends ConsumerState<UnitsTile> { + @override + Widget build(BuildContext context) { + return Column( + children: [ + Container( + margin: const EdgeInsets.symmetric(vertical: 8), + padding: const EdgeInsets.symmetric(vertical: 15), + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: [0.3, 1], + colors: <Color>[Colors.black, Colors.black12]), + ), + //color: Color(0xFF0D113F), + child: ListTile( + contentPadding: + const EdgeInsets.symmetric(vertical: 17, horizontal: 24), + leading: widget.icon != null + ? Icon( + widget.icon, + color: AGLDemoColors.periwinkleColor, + size: 48, + ) + : Padding( + padding: const EdgeInsets.only(right: 24), + child: SvgPicture.asset( + widget.image!, + width: 48, + height: 48, + ), + ), + title: Text( + widget.title, + style: TextStyle( + color: AGLDemoColors.periwinkleColor, + shadows: [ + Helpers.dropShadowRegular, + ], + fontSize: 40), + ), + trailing: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + widget.unitName, + style: TextStyle( + color: AGLDemoColors.periwinkleColor, + shadows: [ + Helpers.dropShadowRegular, + ], + fontSize: 40, + ), + ), + const SizedBox( + width: 24, + ), + const Icon( + Icons.arrow_forward_ios, + color: AGLDemoColors.periwinkleColor, + size: 48, + ), + ], + ), + onTap: widget.voidCallback, + ), + ), + const SizedBox( + height: 8, + ) + ], + ); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/version_info/version_info_screend.dart b/lib/presentation/screens/settings/settings_screens/version_info/version_info_screend.dart new file mode 100644 index 0000000..fce1837 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/version_info/version_info_screend.dart @@ -0,0 +1,83 @@ +import 'package:flutter_ics_homescreen/export.dart'; + +class VersionInfoPage extends ConsumerWidget { + const VersionInfoPage({super.key}); + + static Page<void> page() => + const MaterialPage<void>(child: VersionInfoPage()); + @override + Widget build(BuildContext context, WidgetRef ref) { + return Scaffold( + body: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + CommonTitle( + title: 'Version Information', + hasBackButton: true, + onPressed: () { + context.flow<AppState>().update((state) => AppState.settings); + }, + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 50, horizontal: 144), + child: Column( + children: [ + //Lottie.asset('animations/hybrid_model_yellow_arrow.json'), + Lottie.asset( + 'animations/Logo_JSON.json', + fit: BoxFit.cover, + repeat: false, + ), + const SizedBox( + height: 24, + ), + Container( + height: 140, + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: [0.1, 1], + colors: <Color>[Colors.black, Colors.black12]), + ), + child: ListTile( + contentPadding: const EdgeInsets.only(top: 50, left: 25), + leading: Text( + aglVeriosn, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + ), + const SizedBox( + height: 5, + ), + Container( + height: 140, + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: [0.1, 1], + colors: <Color>[Colors.black, Colors.black12]), + ), + child: ListTile( + contentPadding: const EdgeInsets.only(top: 50, left: 25), + + leading: Text( + kernelVeriosn, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + ), + ], + ), + ), + const SizedBox( + height: 100, + ) + ], + ), + + ); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/wifi/widgets/wifi.dart b/lib/presentation/screens/settings/settings_screens/wifi/widgets/wifi.dart new file mode 100644 index 0000000..cef2014 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/wifi/widgets/wifi.dart @@ -0,0 +1,12 @@ +import '../../../../../../export.dart'; + +class Wifi { + final Icon icon; + final String name; + final bool? isConnected; + Wifi({ + required this.icon, + required this.name, + this.isConnected = false, + }); +} diff --git a/lib/presentation/screens/settings/settings_screens/wifi/widgets/wifi_content.dart b/lib/presentation/screens/settings/settings_screens/wifi/widgets/wifi_content.dart new file mode 100644 index 0000000..2473847 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/wifi/widgets/wifi_content.dart @@ -0,0 +1,150 @@ +import 'package:flutter_ics_homescreen/presentation/custom_icons/custom_icons.dart'; + +import '../../../../../../export.dart'; +import 'wifi.dart'; + +class WifiContent extends ConsumerStatefulWidget { + const WifiContent({ + super.key, + }); + + @override + WifiContentState createState() => WifiContentState(); +} + +class WifiContentState extends ConsumerState<WifiContent> { + final List<Wifi> wifiList = [ + Wifi( + icon: const Icon( + CustomIcons.wifi_4_bar_unlocked, + size: 48, + ), + name: 'box2', + isConnected: true), + Wifi( + icon: const Icon( + CustomIcons.wifi_4_bar_locked, + size: 48, + ), + name: 'WIVACOM_FiberNew_B61E'), + Wifi( + icon: const Icon( + CustomIcons.wifi_3_bar_locked, + size: 48, + ), + name: 'OpenWrt', + ), + Wifi( + icon: const Icon( + CustomIcons.wifi_2_bar_locked, + size: 48, + ), + name: 'kahuna2'), + Wifi( + icon: const Icon( + CustomIcons.wifi_1_bar_locked, + size: 48, + ), + name: 'mip2'), + ]; + Wifi currentWifi = + Wifi(icon: const Icon(Icons.wifi), name: 'box2', isConnected: true); + @override + void initState() { + currentWifi = wifiList[0]; + super.initState(); + } + + void setCurrentWifi(int index) { + setState(() { + currentWifi = wifiList[index]; + }); + } + + @override + Widget build(BuildContext context) { + ref.watch(usersProvider.select((user) => user.selectedUser)); + + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + CommonTitle( + title: "Wifi", + hasBackButton: true, + onPressed: () { + context.flow<AppState>().update((state) => AppState.settings); + }, + ), + Expanded( + child: ListView.separated( + padding: const EdgeInsets.symmetric(vertical: 50, horizontal: 144), + itemCount: wifiList.length, + separatorBuilder: (context, index) { + return const SizedBox( + height: 8, + ); + }, + itemBuilder: (context, index) { + return Container( + height: 130, + + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: currentWifi == wifiList[index] + ? [0, 0.01, 0.8] + : [0.1, 1], + colors: currentWifi == wifiList[index] + ? <Color>[ + Colors.white, + Colors.blue, + const Color.fromARGB(16, 41, 98, 255) + ] + : <Color>[Colors.black, Colors.black12]), + ), + child: ListTile( + contentPadding: + const EdgeInsets.symmetric(vertical: 41, horizontal: 24), + + leading: wifiList[index].icon, + title: Text( + wifiList[index].name, + style: Theme.of(context).textTheme.titleMedium, + ), + onTap: () { + setCurrentWifi(index); + }, + ), + ); + }, + ), + ), + // Container( + // padding: const EdgeInsets.symmetric( + // horizontal: 175, + // ), + // child: ElevatedButton( + // style: ElevatedButton.styleFrom( + // backgroundColor: const Color(0xFF1C2D92), + // ), + // child: const Padding( + // padding: EdgeInsets.symmetric(horizontal: 0, vertical: 15), + // child: Text( + // 'New Profile', + // textAlign: TextAlign.center, + // style: TextStyle( + // color: Color(0xFFC1D8FF), + // fontSize: 20, + // ), + // ), + // ), + // onPressed: () { + // //context.flow<AppState>().update((state) => AppState.newProfile); + // }, + // ), + // ), + ], + ); + } +} diff --git a/lib/presentation/screens/settings/settings_screens/wifi/wifi_screen.dart b/lib/presentation/screens/settings/settings_screens/wifi/wifi_screen.dart new file mode 100644 index 0000000..1f85ae8 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/wifi/wifi_screen.dart @@ -0,0 +1,17 @@ + +import 'package:flutter_ics_homescreen/export.dart'; +import 'widgets/wifi_content.dart'; + +class WifiPage extends StatelessWidget { + const WifiPage({super.key}); + + static Page<void> page() => const MaterialPage<void>(child: WifiPage()); + @override + Widget build(BuildContext context) { + //final currentUser = + //ref.watch(usersProvider.select((user) => user.selectedUser)); + + return const Scaffold(body: WifiContent()); + } +} + diff --git a/lib/presentation/screens/settings/settings_screens/wired/wired_screen.dart b/lib/presentation/screens/settings/settings_screens/wired/wired_screen.dart new file mode 100644 index 0000000..916b1b6 --- /dev/null +++ b/lib/presentation/screens/settings/settings_screens/wired/wired_screen.dart @@ -0,0 +1,76 @@ +import 'package:flutter_ics_homescreen/export.dart'; + +class WiredPage extends ConsumerWidget { + const WiredPage({super.key}); + + static Page<void> page() => const MaterialPage<void>(child: WiredPage()); + @override + Widget build(BuildContext context, WidgetRef ref) { + return Scaffold( + body: Column( + children: [ + CommonTitle( + title: 'Wired', + hasBackButton: true, + onPressed: () { + context.flow<AppState>().update((state) => AppState.settings); + }, + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 50, horizontal: 80), + child: Container( + height: 130, + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: [ + 0, + 0.01, + 0.8 + ], + colors: <Color>[ + Colors.white, + Colors.blue, + Color.fromARGB(16, 41, 98, 255) + ]), + ), + child: ListTile( + contentPadding: + const EdgeInsets.symmetric(vertical: 41, horizontal: 24), + + title: const Text( + 'hernet_0090451v407b_cable', + style: TextStyle(color: Colors.white, fontSize: 40), + ), + subtitle: const Text( + 'connected, 192.168.234.120', + style: TextStyle(color: Colors.white, fontSize: 26), + ), + trailing: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF1C2D92), + side: const BorderSide(color: Color(0xFF285DF4), width: 2), + ), + child: const Padding( + padding: + EdgeInsets.symmetric(vertical: 15.0, horizontal: 0), + child: Text( + + 'Configure', + style: TextStyle( + color: Color(0xFFC1D8FF), + fontSize: 26, + ), + ), + ), + onPressed: () {}, + ), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/screens/settings/widgets/settings_content.dart b/lib/presentation/screens/settings/widgets/settings_content.dart new file mode 100644 index 0000000..f73bf6d --- /dev/null +++ b/lib/presentation/screens/settings/widgets/settings_content.dart @@ -0,0 +1,95 @@ +import 'package:flutter_ics_homescreen/export.dart'; + +import '../../../custom_icons/custom_icons.dart'; + +class Settings extends StatelessWidget { + const Settings({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.start, + //crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const CommonTitle( + title: 'Settings', + ), + Expanded( + child: ListView( + padding: const EdgeInsets.symmetric(vertical: 50, horizontal: 144), + children: [ + SettingsTile( + icon: Icons.calendar_month_outlined, + title: 'Date & Time', + hasSwich: false, + voidCallback: () async { + context + .flow<AppState>() + .update((next) => AppState.dateTime); + }), + SettingsTile( + icon: Icons.bluetooth, + title: 'Bluetooth', + hasSwich: true, + voidCallback: () { + context + .flow<AppState>() + .update((next) => AppState.bluetooth); + }), + SettingsTile( + icon: Icons.wifi, + title: 'Wifi', + hasSwich: true, + voidCallback: () { + context.flow<AppState>().update((next) => AppState.wifi); + }), + SettingsTile( + icon: CustomIcons.wiredicon, + title: 'Wired', + hasSwich: false, + voidCallback: () { + context.flow<AppState>().update((next) => AppState.wired); + }), + SettingsTile( + icon: Icons.tune, + title: 'Audio Settings', + hasSwich: false, + voidCallback: () { + context + .flow<AppState>() + .update((next) => AppState.audioSettings); + }), + SettingsTile( + icon: Icons.person_2_outlined, + title: 'Profiles', + hasSwich: false, + voidCallback: () { + context + .flow<AppState>() + .update((next) => AppState.profiles); + }), + SettingsTile( + icon: Icons.straighten, + title: 'Units', + hasSwich: false, + voidCallback: () { + context.flow<AppState>().update((next) => AppState.units); + }), + SettingsTile( + icon: Icons.help_sharp, + title: 'Version Info', + hasSwich: false, + voidCallback: () { + context + .flow<AppState>() + .update((next) => AppState.versionInfo); + }), + ], + ), + ), + ], + ); + } +} diff --git a/lib/presentation/screens/settings/widgets/settings_list_tile.dart b/lib/presentation/screens/settings/widgets/settings_list_tile.dart new file mode 100644 index 0000000..4720001 --- /dev/null +++ b/lib/presentation/screens/settings/widgets/settings_list_tile.dart @@ -0,0 +1,234 @@ +import 'package:flutter_ics_homescreen/export.dart'; + +class SettingsTile extends ConsumerStatefulWidget { + final IconData icon; + final String title; + final bool hasSwich; + final VoidCallback voidCallback; + const SettingsTile({ + Key? key, + required this.icon, + required this.title, + required this.hasSwich, + required this.voidCallback, + }) : super(key: key); + + @override + SettingsTileState createState() => SettingsTileState(); +} + +class SettingsTileState extends ConsumerState<SettingsTile> { + bool isSwitchOn = true; + @override + Widget build(BuildContext context) { + final signal = ref.watch(signalsProvider.select((signal) => signal)); + if (widget.title == 'Bluetooth') { + isSwitchOn = signal.isBluetoothConnected; + } else if (widget.title == 'Wifi') { + isSwitchOn = signal.isWifiConnected; + } else { + // isSwitchOn = false; + } + return Column( + children: [ + GestureDetector( + onTap: isSwitchOn ? widget.voidCallback : () {}, + child: Container( + height: 130, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + stops: isSwitchOn ? [0.3, 1] : [0.8, 1], + colors: isSwitchOn + ? <Color>[Colors.black, Colors.black12] + : <Color>[ + const Color.fromARGB(50, 0, 0, 0), + Colors.transparent + ], + ), + ), + child: Card( + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(12), + // ), + color: Colors.transparent, + elevation: 5, + child: Padding( + padding: + const EdgeInsets.symmetric(vertical: 0, horizontal: 24), + child: Row( + children: [ + Icon( + widget.icon, + color: AGLDemoColors.periwinkleColor, + size: 48, + ), + const SizedBox(width: 24), + Expanded( + child: Text( + widget.title, + style: const TextStyle(fontSize: 40), + ), + ), + widget.hasSwich + ? Container( + width: 126, + height: 80, + decoration: const ShapeDecoration( + color: + AGLDemoColors.gradientBackgroundDarkColor, + shape: StadiumBorder( + side: BorderSide( + color: Color(0xFF5477D4), + width: 4, + )), + ), + child: FittedBox( + fit: BoxFit.fill, + child: Switch( + value: isSwitchOn, + onChanged: (bool value) { + switch (widget.title) { + case 'Bluetooth': + ref + .read(signalsProvider.notifier) + .toggleBluetooth(); + break; + case 'Wifi': + ref + .read(signalsProvider.notifier) + .toggleWifi(); + break; + default: + } + setState(() { + isSwitchOn = value; + }); + // This is called when the user toggles the switch. + }, + inactiveTrackColor: Colors.transparent, + activeTrackColor: Colors.transparent, + thumbColor: + MaterialStateProperty.all<Color>( + AGLDemoColors.periwinkleColor)), + ), + ) + : const SizedBox(), + ], + ), + ), + ) + // ListTile( + // contentPadding: + // const EdgeInsets.symmetric(vertical: 41, horizontal: 24), + // minLeadingWidth: 55.0, + // minVerticalPadding: 0.0, + // leading: Icon( + // widget.icon, + // color: AGLDemoColors.periwinkleColor, + // size: 48, + // ), + // title: Text( + // widget.title, + // style: const TextStyle(fontSize: 40), + // ), + // enabled: isSwitchOn, + // trailing: widget.hasSwich + // ? Container( + // width: 126, + // height: 80, + // decoration: const ShapeDecoration( + // color: AGLDemoColors.gradientBackgroundDarkColor, + // shape: StadiumBorder( + // side: BorderSide( + // color: Color(0xFF5477D4), + // //color: Colors.amber, + + // width: 1.5, + // )), + // ), + // child: Switch( + // value: isSwitchOn, + // onChanged: (bool value) { + // switch (widget.title) { + // case 'Bluetooth': + // ref + // .read(signalsProvider.notifier) + // .toggleBluetooth(); + // break; + // case 'Wifi': + // ref.read(signalsProvider.notifier).toggleWifi(); + // break; + // default: + // } + // setState(() { + // isSwitchOn = value; + // }); + // // This is called when the user toggles the switch. + // }, + // inactiveTrackColor: Colors.transparent, + // activeTrackColor: Colors.transparent, + // thumbColor: MaterialStateProperty.all<Color>( + // AGLDemoColors.periwinkleColor)), + // ) + // : const SizedBox( + // //Spacer + // height: 80, + // ), + // onTap: widget.voidCallback, + + // ), + ), + ), + const SizedBox( + height: 8, + ) + ], + ); + } +} + +// List<SettingsTile> settingsList = [ +// SettingsTile( +// icon: Icons.calendar_month_outlined, +// title: 'Date & Time', +// hasSwich: false, +// voidCallback: () {}), +// SettingsTile( +// icon: Icons.bluetooth, +// title: 'Bluetooth', +// hasSwich: true, +// voidCallback: () {}), +// SettingsTile( +// icon: Icons.wifi, +// title: 'Wifi', +// hasSwich: true, +// voidCallback: () {}, +// ), +// SettingsTile( +// icon: Icons.settings, +// title: 'Wired', +// hasSwich: false, +// voidCallback: () {}), +// SettingsTile( +// icon: Icons.tune, +// title: 'Audio Settings', +// hasSwich: false, +// voidCallback: () {}), +// SettingsTile( +// icon: Icons.person_2_outlined, +// title: 'Profiles', +// hasSwich: false, +// voidCallback: () {}), +// SettingsTile( +// icon: Icons.straighten, +// title: 'Units', +// hasSwich: false, +// voidCallback: () {}), +// SettingsTile( +// icon: Icons.help_sharp, +// title: 'Veriosn Info', +// hasSwich: false, +// voidCallback: () {}), +// ]; |