From 0e53a649097632290b750b17fc96c2410fc0f473 Mon Sep 17 00:00:00 2001 From: CodeDoctorDE Date: Wed, 29 May 2024 17:27:04 +0200 Subject: [PATCH] Add connect page --- app/lib/l10n/app_en.arb | 7 +- app/lib/pages/home/connect.dart | 105 ++++++++++++ app/lib/pages/home/create.dart | 272 ++++++++++++++++---------------- app/lib/pages/home/packs.dart | 3 + app/lib/pages/home/page.dart | 7 +- 5 files changed, 255 insertions(+), 139 deletions(-) create mode 100644 app/lib/pages/home/connect.dart diff --git a/app/lib/l10n/app_en.arb b/app/lib/l10n/app_en.arb index 6b52c96..137e3dd 100644 --- a/app/lib/l10n/app_en.arb +++ b/app/lib/l10n/app_en.arb @@ -80,5 +80,10 @@ "systemLocale": "System locale", "packs": "Packs", "checkForUpdatesWarning": "Performing a check for updates will connect to the Butterfly website to get the information.", - "comingSoon": "Coming soon" + "comingSoon": "Coming soon", + "templates": "Templates", + "custom": "Custom", + "installed": "Installed", + "details": "Details", + "play": "Play" } diff --git a/app/lib/pages/home/connect.dart b/app/lib/pages/home/connect.dart new file mode 100644 index 0000000..1f38e1a --- /dev/null +++ b/app/lib/pages/home/connect.dart @@ -0,0 +1,105 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:material_leap/material_leap.dart'; +import 'package:phosphor_flutter/phosphor_flutter.dart'; + +class ConnectDialog extends StatefulWidget { + const ConnectDialog({super.key}); + + @override + State createState() => _ConnectDialogState(); +} + +class _ConnectDialogState extends State { + int _selectedIndex = 0; + bool _isMobileOpen = false; + + @override + Widget build(BuildContext context) { + final isMobile = MediaQuery.sizeOf(context).width < LeapBreakpoints.medium; + final servers = List.generate(10, (index) => 'Server ${index + 1}'); + final currentIndex = _selectedIndex; + final detailsChildren = [ + const Text( + '''Labore commodo amet nisi ad ad aliquip minim. Do minim eiusmod sunt pariatur ullamco mollit nulla consequat enim Lorem deserunt amet. Velit cupidatat officia elit consectetur cillum culpa sunt pariatur magna cupidatat culpa. Occaecat ad mollit qui laboris do nostrud. + +Ad id adipisicing sunt laboris mollit deserunt id adipisicing culpa. Consequat amet ea velit culpa quis nostrud ullamco ipsum aliquip nostrud labore ipsum irure. Proident aliquip nulla labore aliquip tempor minim velit excepteur ipsum incididunt. Dolore tempor officia voluptate ipsum. Et occaecat deserunt sint id incididunt nisi duis commodo elit pariatur magna voluptate. Id incididunt minim consequat irure laboris culpa laborum ipsum. Dolor fugiat laborum dolor sint adipisicing fugiat. + +Lorem ullamco laboris do proident occaecat mollit aliquip minim. Do irure consectetur ut do laborum deserunt aliquip dolore consectetur eu. Cupidatat consequat ea occaecat reprehenderit minim voluptate fugiat cillum do labore in. Ullamco eiusmod occaecat eu voluptate elit cupidatat non proident. Reprehenderit Lorem elit est commodo in duis Lorem sunt esse. + +Nisi sunt irure consectetur officia occaecat. Elit do consequat sit laboris laboris sunt est ex. Amet laboris aliqua nisi anim incididunt pariatur ex. Duis eiusmod Lorem aliqua minim eiusmod laborum sit nulla. Officia eu cupidatat veniam ad mollit sint consectetur laboris elit ipsum. Laborum officia non in aute ut voluptate Lorem culpa id labore qui ea minim ex.''', + ), + ]; + final playButton = SizedBox( + height: 48, + child: FilledButton.icon( + icon: const Icon(PhosphorIconsLight.play), + label: Text(AppLocalizations.of(context).play), + onPressed: () => Navigator.of(context).pop(), + ), + ); + final listView = ListView.builder( + itemCount: servers.length, + itemBuilder: (context, index) => ListTile( + title: Text(servers[index]), + onTap: () { + setState(() { + _selectedIndex = index; + _isMobileOpen = isMobile; + }); + if (isMobile) { + showLeapBottomSheet( + context: context, + title: servers[_selectedIndex], + childrenBuilder: (context) => [ + ...detailsChildren, + const SizedBox(height: 16), + playButton, + ], + ).then((_) { + if (mounted) setState(() => _isMobileOpen = false); + }); + } + }, + selected: currentIndex == index && (!isMobile || _isMobileOpen), + ), + ); + final details = Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + servers[currentIndex], + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 16), + Expanded( + child: ListView( + children: detailsChildren, + ), + ), + const SizedBox(height: 16), + playButton, + ], + ); + return ResponsiveAlertDialog( + title: Text(AppLocalizations.of(context).connect), + leading: IconButton.outlined( + icon: const Icon(PhosphorIconsLight.x), + onPressed: () => Navigator.of(context).pop(), + ), + constraints: const BoxConstraints( + maxWidth: LeapBreakpoints.expanded, + maxHeight: 700, + ), + content: Row( + children: [ + Expanded(child: listView), + if (!isMobile) ...[ + const VerticalDivider(), + Expanded(child: details), + ], + ], + ), + ); + } +} diff --git a/app/lib/pages/home/create.dart b/app/lib/pages/home/create.dart index 7a8a1c5..75d2e94 100644 --- a/app/lib/pages/home/create.dart +++ b/app/lib/pages/home/create.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:material_leap/material_leap.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; @@ -34,147 +35,150 @@ class _CreateDialogState extends State @override Widget build(BuildContext context) { final isMobile = MediaQuery.sizeOf(context).width < LeapBreakpoints.medium; - return ResponsiveAlertDialog( - title: const Text('Create'), - constraints: const BoxConstraints( - maxWidth: LeapBreakpoints.expanded, - maxHeight: 700, - ), - content: Builder(builder: (context) { - final selections = Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - TabBar( - controller: _tabController, - indicatorSize: TabBarIndicatorSize.tab, - tabs: const [ - HorizontalTab( - icon: PhosphorIcon(PhosphorIconsLight.folder), - label: Text('Templates'), + final selections = Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + TabBar( + controller: _tabController, + indicatorSize: TabBarIndicatorSize.tab, + tabs: [ + HorizontalTab( + icon: const PhosphorIcon(PhosphorIconsLight.folder), + label: Text(AppLocalizations.of(context).installed), + ), + HorizontalTab( + icon: const PhosphorIcon(PhosphorIconsLight.globe), + label: Text(AppLocalizations.of(context).custom), + ), + ], + ), + const SizedBox(height: 16), + Expanded( + child: TabBarView( + controller: _tabController, + children: [ + Material( + type: MaterialType.transparency, + child: ListView.builder( + itemCount: 30, + itemBuilder: (context, index) { + return ListTile( + title: Text('Template ${index + 1}'), + onTap: () => Navigator.of(context).pop(), + ); + }, ), - HorizontalTab( - icon: PhosphorIcon(PhosphorIconsLight.globe), - label: Text('Custom'), + ), + Column(children: [ + TabBar.secondary( + tabs: const [ + HorizontalTab( + label: Text('Packs'), + icon: Icon(PhosphorIconsLight.package)), + HorizontalTab( + label: Text('Configuration'), + icon: Icon(PhosphorIconsLight.wrench)), + ], + tabAlignment: TabAlignment.center, + controller: _customTabController, ), - ], - ), - const SizedBox(height: 16), - Expanded( - child: TabBarView( - controller: _tabController, - children: [ - Material( + const SizedBox(height: 8), + Expanded( + child: Material( type: MaterialType.transparency, - child: ListView.builder( - itemCount: 30, - itemBuilder: (context, index) { - return ListTile( - title: Text('Template ${index + 1}'), - onTap: () => Navigator.of(context).pop(), - ); - }, - ), - ), - Column(children: [ - TabBar.secondary( - tabs: const [ - HorizontalTab( - label: Text('Packs'), - icon: Icon(PhosphorIconsLight.package)), - HorizontalTab( - label: Text('Configuration'), - icon: Icon(PhosphorIconsLight.wrench)), - ], - tabAlignment: TabAlignment.center, + child: TabBarView( controller: _customTabController, - ), - const SizedBox(height: 8), - Expanded( - child: Material( - type: MaterialType.transparency, - child: TabBarView( - controller: _customTabController, + children: [ + ListView.builder( + itemCount: 30, + shrinkWrap: true, + itemBuilder: (context, index) { + return CheckboxListTile( + title: Text('Custom ${index + 1}'), + value: false, + onChanged: (bool? value) {}, + ); + }, + ), + ListView( children: [ - ListView.builder( - itemCount: 30, - shrinkWrap: true, - itemBuilder: (context, index) { - return CheckboxListTile( - title: Text('Custom ${index + 1}'), - value: false, - onChanged: (bool? value) {}, - ); - }, + ListTile( + title: const Text('Background'), + subtitle: const Text('Not set'), + onTap: () => Navigator.of(context).pop(), + ), + const ListTile( + title: Text('Rules'), + subtitle: Text('Coming soon'), ), - ListView( - children: [ - ListTile( - title: const Text('Background'), - subtitle: const Text('Not set'), - onTap: () => Navigator.of(context).pop(), - ), - const ListTile( - title: Text('Rules'), - subtitle: Text('Coming soon'), - ), - ], - ) ], - ), - ), + ) + ], ), - ]), - ], - ), - ), - ], - ); - final details = ListView( - children: [ - Text('Details', style: Theme.of(context).textTheme.headlineMedium), - const SizedBox(height: 16), - TextFormField( - decoration: const InputDecoration( - labelText: 'Name', hintText: 'Enter a name', filled: true), - ), - const SizedBox(height: 16), - TextFormField( - decoration: const InputDecoration( - labelText: 'Description', - hintText: 'Enter a description', - border: OutlineInputBorder(), - ), - minLines: 3, - maxLines: 5, - ), - ], - ); - return IndexedStack( - index: isMobile ? 0 : 1, - key: _pageKey, - children: [ - PageView( - controller: _pageController, - children: [ - selections, - details, - ], - onPageChanged: (value) => - setState(() => _infoView = value.toInt() == 1), - ), - Row( - children: [ - Expanded(child: selections), - const SizedBox(width: 16), - const VerticalDivider(), - const SizedBox(width: 16), - Expanded(child: details), - ], - ) - ], - ); - }), + ), + ), + ]), + ], + ), + ), + ], + ); + final details = ListView( + children: [ + Text('Details', style: Theme.of(context).textTheme.headlineMedium), + const SizedBox(height: 16), + TextFormField( + decoration: const InputDecoration( + labelText: 'Name', hintText: 'Enter a name', filled: true), + ), + const SizedBox(height: 16), + TextFormField( + decoration: const InputDecoration( + labelText: 'Description', + hintText: 'Enter a description', + border: OutlineInputBorder(), + ), + minLines: 3, + maxLines: 5, + ), + ], + ); + return ResponsiveAlertDialog( + title: const Text('Create'), + constraints: const BoxConstraints( + maxWidth: LeapBreakpoints.expanded, + maxHeight: 700, + ), + content: IndexedStack( + index: isMobile ? 0 : 1, + key: _pageKey, + children: [ + PageView( + controller: _pageController, + children: [ + selections, + details, + ], + onPageChanged: (value) => + setState(() => _infoView = value.toInt() == 1), + ), + Row( + children: [ + Expanded(child: selections), + const SizedBox(width: 16), + const VerticalDivider(), + const SizedBox(width: 16), + Expanded(child: details), + ], + ) + ], + ), actions: [ + TextButton.icon( + onPressed: () => Navigator.of(context).pop(), + label: const Text('Cancel'), + icon: const Icon(PhosphorIconsLight.prohibit), + ), if (isMobile && !_infoView) ...[ FilledButton.icon( icon: const Icon(PhosphorIconsBold.arrowRight), @@ -201,10 +205,6 @@ class _CreateDialogState extends State ), ] ], - leading: IconButton.outlined( - icon: const Icon(PhosphorIconsLight.x), - onPressed: () => Navigator.of(context).pop(), - ), ); } } diff --git a/app/lib/pages/home/packs.dart b/app/lib/pages/home/packs.dart index 95f49fa..20d360d 100644 --- a/app/lib/pages/home/packs.dart +++ b/app/lib/pages/home/packs.dart @@ -85,6 +85,9 @@ class _PacksDialogState extends State Center( child: Text(AppLocalizations.of(context).comingSoon), ), + Center( + child: Text(AppLocalizations.of(context).comingSoon), + ), ], ), ), diff --git a/app/lib/pages/home/page.dart b/app/lib/pages/home/page.dart index abcc921..c28d77c 100644 --- a/app/lib/pages/home/page.dart +++ b/app/lib/pages/home/page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; import 'package:material_leap/material_leap.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; import 'package:quokka/cubits/settings.dart'; import 'package:quokka/main.dart'; +import 'package:quokka/pages/home/connect.dart'; import 'package:quokka/pages/home/packs.dart'; import 'package:quokka/pages/home/play.dart'; @@ -57,7 +57,10 @@ class HomePage extends StatelessWidget { ( 'Connect', PhosphorIconsLight.plugsConnected, - () => context.push('/board'), + () => showDialog( + context: context, + builder: (context) => + const ConnectDialog()), ), ( 'Packs',