From e6607181508790bdc7720c67004cb6d59d0f0217 Mon Sep 17 00:00:00 2001 From: Nexerate Date: Mon, 14 Oct 2024 21:35:39 +0200 Subject: [PATCH] Fix foldouts --- assets/icons/lucide/chevron_down.svg | 3 + lib/components/separator.dart | 13 +-- lib/pages/home/bedpres.dart | 2 +- lib/pages/home/event_card.dart | 2 +- lib/pages/menu/menu_page.dart | 115 ++++++++++++++++++--------- lib/pages/menu/profile_card.dart | 4 +- lib/pages/menu/settings.dart | 50 ++++++++---- lib/services/authenticator.dart | 8 +- lib/theme/themed_icon.dart | 1 + pubspec.yaml | 2 +- 10 files changed, 130 insertions(+), 70 deletions(-) create mode 100644 assets/icons/lucide/chevron_down.svg diff --git a/assets/icons/lucide/chevron_down.svg b/assets/icons/lucide/chevron_down.svg new file mode 100644 index 00000000..6d7cc3e5 --- /dev/null +++ b/assets/icons/lucide/chevron_down.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/lib/components/separator.dart b/lib/components/separator.dart index 17255174..6114a1c8 100644 --- a/lib/components/separator.dart +++ b/lib/components/separator.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:online/theme/theme.dart'; class Separator extends StatelessWidget { const Separator({super.key, this.margin = 0, this.length, this.axis = Axis.horizontal}); @@ -14,17 +15,7 @@ class Separator extends StatelessWidget { height: h ? 1 : length, width: !h ? 1 : length, margin: EdgeInsets.symmetric(vertical: h ? margin : 0, horizontal: !h ? margin : 0), - decoration: BoxDecoration( - gradient: LinearGradient( - begin: h ? Alignment.centerLeft : Alignment.bottomCenter, - end: h ? Alignment.centerRight : Alignment.topCenter, - colors: const [ - Color(0xFF000212), - Color(0xFF2E3440), - Color(0xFF000212), - ], - ), - ), + color: OnlineTheme.current.border, ); } } diff --git a/lib/pages/home/bedpres.dart b/lib/pages/home/bedpres.dart index 8a343890..49c58001 100644 --- a/lib/pages/home/bedpres.dart +++ b/lib/pages/home/bedpres.dart @@ -260,7 +260,7 @@ class BedpresCard extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconLabel(icon: IconType.dateTime, label: formatDate()), - IconLabel(icon: IconType.usersFilled, label: participants(), iconSize: 16), + IconLabel(icon: IconType.users, label: participants(), iconSize: 16), ], ), ), diff --git a/lib/pages/home/event_card.dart b/lib/pages/home/event_card.dart index 6430e924..375275df 100644 --- a/lib/pages/home/event_card.dart +++ b/lib/pages/home/event_card.dart @@ -218,7 +218,7 @@ class EventCard extends StatelessWidget { fontWeight: 5, ), IconLabel( - icon: IconType.usersFilled, + icon: IconType.users, label: participants(), color: OnlineTheme.current.mutedForeground, iconSize: 16, diff --git a/lib/pages/menu/menu_page.dart b/lib/pages/menu/menu_page.dart index 58b2cc72..26df52de 100644 --- a/lib/pages/menu/menu_page.dart +++ b/lib/pages/menu/menu_page.dart @@ -19,6 +19,76 @@ import '/services/env.dart'; import '/theme/theme.dart'; import '/theme/themed_icon.dart'; +class Foldout extends StatefulWidget { + final Widget? leading; + final Widget? trailing; + final String title; + final List children; + + const Foldout({ + super.key, + required this.title, + required this.children, + this.leading, + this.trailing, + }); + + @override + State createState() => FoldoutState(); +} + +class FoldoutState extends State { + bool open = false; + + Widget header() { + return Listener( + onPointerUp: (event) { + setState(() { + open = !open; + }); + }, + behavior: HitTestBehavior.opaque, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + if (widget.leading != null) widget.leading!, + Expanded(child: Text(widget.title, style: OnlineTheme.textStyle())), + AnimatedRotation( + turns: open ? -0.5 : 0, + duration: Duration(milliseconds: 100), + child: widget.trailing ?? + Lucide( + LucideIcon.chevronDown, + size: 20, + ), + ), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + header(), + ClipRect( + child: AnimatedAlign( + alignment: open ? Alignment.topCenter : Alignment.topCenter, + heightFactor: open ? 1.0 : 0.0, + duration: Duration(milliseconds: 200), + curve: Curves.easeInOut, + child: Column( + children: widget.children, + ), + ), + ), + ], + ); + } +} + class MenuPage extends StatefulWidget { const MenuPage({super.key}); @@ -128,41 +198,12 @@ class MenuPageState extends State { ); } - static Widget accordion(String title, Widget icon, List children) { - return Accordion( - headerBackgroundColor: Colors.transparent, - contentBackgroundColor: OnlineTheme.current.card, - contentBorderWidth: 0, - contentHorizontalPadding: 0, - leftIcon: icon, - scaleWhenAnimating: false, - headerPadding: EdgeInsets.zero, - paddingListTop: 0, - paddingListBottom: 0, - paddingListHorizontal: 0, - paddingBetweenClosedSections: 0, - initialOpeningSequenceDelay: 0, - disableScrolling: true, - openAndCloseAnimation: true, - paddingBetweenOpenSections: 0, - contentVerticalPadding: 0, - children: [ - AccordionSection( - header: Text(title, style: OnlineTheme.textStyle()), - content: Column( - children: children, - ), - ), - ], - ); - } - Widget helpAndSupportCard() { return OnlineCard( - child: accordion( - "Hjelp og Støtte", - Lucide(LucideIcon.users, size: 24), - [ + child: Foldout( + title: "Hjelp og Støtte", + leading: Padding(padding: EdgeInsets.only(right: 16), child: Lucide(LucideIcon.users, size: 24)), + children: [ const SizedBox(height: 16), Row( children: [ @@ -242,10 +283,10 @@ class MenuPageState extends State { Widget settingsAndPrivacyCard() { return OnlineCard( - child: accordion( - 'Din Data', - Lucide(LucideIcon.database, size: 24), - [ + child: Foldout( + title: 'Din Data', + leading: Padding(padding: EdgeInsets.only(right: 16), child: Lucide(LucideIcon.database, size: 24)), + children: [ const SizedBox(height: 16), AnimatedButton(onTap: () { io.Client.launchInBrowser('https://online.ntnu.no/profile/settings/userdata'); diff --git a/lib/pages/menu/profile_card.dart b/lib/pages/menu/profile_card.dart index 241442eb..d5a6529b 100644 --- a/lib/pages/menu/profile_card.dart +++ b/lib/pages/menu/profile_card.dart @@ -71,9 +71,9 @@ class ProfileCard extends StaticPage { const SizedBox(width: 24), ValueListenableBuilder( valueListenable: Client.userCache, - builder: (contex, value, child) { + builder: (contex, user, child) { return Text( - "${value?.firstName} ${value?.lastName}", + "${user?.firstName} ${user?.lastName}", style: OnlineTheme.textStyle(), ); }, diff --git a/lib/pages/menu/settings.dart b/lib/pages/menu/settings.dart index 3c93d55b..6ff3936d 100644 --- a/lib/pages/menu/settings.dart +++ b/lib/pages/menu/settings.dart @@ -108,22 +108,42 @@ class SettingsPageState extends State { @override Widget build(BuildContext context) { return OnlineCard( - child: MenuPageState.accordion( - "Varslinger", - Lucide(LucideIcon.notification, size: 24), - eventCategories.keys.map((String key) { - return CheckboxListTile( - title: Text(key, style: OnlineTheme.textStyle()), - value: eventCategories[key], - activeColor: OnlineTheme.current.pos, - checkColor: OnlineTheme.current.fg, - contentPadding: EdgeInsets.zero, - onChanged: (bool? value) { - _handleSubscription(key, value); - }, - ); - }).toList(), + child: Foldout( + leading: Padding(padding: EdgeInsets.only(right: 16), child: Lucide(LucideIcon.notification, size: 24)), + title: 'Varslinger', + children: eventCategories.keys.map( + (String key) { + return CheckboxListTile( + title: Text(key, style: OnlineTheme.textStyle()), + value: eventCategories[key], + activeColor: OnlineTheme.current.pos, + checkColor: OnlineTheme.current.fg, + contentPadding: EdgeInsets.zero, + onChanged: (bool? value) { + _handleSubscription(key, value); + }, + ); + }, + ).toList(), ), ); + // return OnlineCard( + // child: MenuPageState.accordion( + // "Varslinger", + // Lucide(LucideIcon.notification, size: 24), + // eventCategories.keys.map((String key) { + // return CheckboxListTile( + // title: Text(key, style: OnlineTheme.textStyle()), + // value: eventCategories[key], + // activeColor: OnlineTheme.current.pos, + // checkColor: OnlineTheme.current.fg, + // contentPadding: EdgeInsets.zero, + // onChanged: (bool? value) { + // _handleSubscription(key, value); + // }, + // ); + // }).toList(), + // ), + // ); } } diff --git a/lib/services/authenticator.dart b/lib/services/authenticator.dart index 84c2e80a..8a04ba8f 100644 --- a/lib/services/authenticator.dart +++ b/lib/services/authenticator.dart @@ -46,9 +46,13 @@ abstract class Authenticator { //final scheme = dotenv.env['AUTH0_CUSTOM_SCHEME']; final response = await auth0!.webAuthentication(scheme: dotenv.env['AUTH0_CUSTOM_SCHEME']).login(); await auth0!.credentialsManager.storeCredentials(response); - await Client.getUserProfile(); + loggedIn.value = true; - return credentials = response; + credentials = response; + + await Client.getUserProfile(); + + return response; } catch (e) { // User cancelled login return null; diff --git a/lib/theme/themed_icon.dart b/lib/theme/themed_icon.dart index 7f245810..68da67e0 100644 --- a/lib/theme/themed_icon.dart +++ b/lib/theme/themed_icon.dart @@ -97,6 +97,7 @@ enum LucideIcon { bug, database, notification, + chevronDown, } class Lucide extends StatelessWidget { diff --git a/pubspec.yaml b/pubspec.yaml index 2b2d7911..151efad3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: online description: Online App publish_to: "none" -version: 1.1.0 +version: 1.1.2 environment: sdk: ">=3.1.0 <4.0.0"