From a5539b4bead4276fb126bae4bd0a06ad3971fe7a Mon Sep 17 00:00:00 2001 From: ggurdin <46800240+ggurdin@users.noreply.github.com> Date: Tue, 20 May 2025 16:45:58 -0400 Subject: [PATCH] 2655 tweaks to spacechat navigation (#2859) * chore: update parent space navigation * refactor: show space navigation rail on mobile --- assets/l10n/intl_en.arb | 3 +- lib/config/app_config.dart | 3 + lib/config/routes.dart | 87 +++--- lib/config/setting_keys.dart | 4 + lib/pages/chat_list/chat_list_body.dart | 3 +- lib/pages/chat_list/chat_list_view.dart | 9 +- lib/pages/chat_list/navi_rail_item.dart | 9 +- lib/pages/chat_list/space_view.dart | 167 +++++++---- lib/pages/settings/settings_view.dart | 6 +- .../settings_style/settings_style_view.dart | 8 + .../suggestions_page.dart | 57 ++-- .../learning_progress_indicators.dart | 265 +++++++++--------- lib/pangea/analytics_summary/level_badge.dart | 5 +- .../analytics_summary/progress_indicator.dart | 20 +- lib/pangea/layouts/bottom_nav_layout.dart | 96 ------- lib/widgets/matrix.dart | 6 + lib/widgets/navigation_rail.dart | 51 +++- 17 files changed, 422 insertions(+), 377 deletions(-) delete mode 100644 lib/pangea/layouts/bottom_nav_layout.dart diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index d610de1dd..68fc0b0da 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -4943,5 +4943,6 @@ "launchActivityToChats": "Launch activity to chats", "searchChats": "Search chats", "selectChats": "Select chats", - "selectChatToStart": "Complete! Select a chat to start" + "selectChatToStart": "Complete! Select a chat to start", + "displayNavigationRail": "Show navigation rail on mobile" } diff --git a/lib/config/app_config.dart b/lib/config/app_config.dart index 33a97c5cc..d04d20be0 100644 --- a/lib/config/app_config.dart +++ b/lib/config/app_config.dart @@ -134,6 +134,9 @@ abstract class AppConfig { static bool swipeRightToLeftToReply = true; static bool? sendOnEnter; static bool showPresences = true; + // #Pangea + static bool displayNavigationRail = true; + // Pangea# static bool experimentalVoip = false; static const bool hideTypingUsernames = false; static const bool hideAllStateEvents = false; diff --git a/lib/config/routes.dart b/lib/config/routes.dart index d014a23a7..e1d6bd72a 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -33,7 +33,6 @@ import 'package:fluffychat/pangea/activity_generator/activity_generator.dart'; import 'package:fluffychat/pangea/activity_planner/activity_planner_page.dart'; import 'package:fluffychat/pangea/activity_suggestions/suggestions_page.dart'; import 'package:fluffychat/pangea/guard/p_vguard.dart'; -import 'package:fluffychat/pangea/layouts/bottom_nav_layout.dart'; import 'package:fluffychat/pangea/learning_settings/pages/settings_learning.dart'; import 'package:fluffychat/pangea/login/pages/login_or_signup_view.dart'; import 'package:fluffychat/pangea/login/pages/signup.dart'; @@ -210,15 +209,7 @@ abstract class AppRoutes { ), sideView: child, ) - // #Pangea - // : child, - : FluffyThemes.isColumnMode(context) || - (state.fullPath?.split("/").reversed.elementAt(1) == - 'rooms' && - state.pathParameters['roomid'] != null) - ? child - : BottomNavLayout(mainView: child), - // Pangea# + : child, ), routes: [ GoRoute( @@ -352,6 +343,39 @@ abstract class AppRoutes { ), redirect: loggedOutRedirect, ), + // #Pangea + GoRoute( + path: 'homepage', + redirect: loggedOutRedirect, + pageBuilder: (context, state) => defaultPageBuilder( + context, + state, + const SuggestionsPage(), + ), + routes: [ + ...newRoomRoutes, + GoRoute( + path: '/planner', + pageBuilder: (context, state) => defaultPageBuilder( + context, + state, + const ActivityPlannerPage(), + ), + redirect: loggedOutRedirect, + routes: [ + GoRoute( + path: '/generator', + redirect: loggedOutRedirect, + pageBuilder: (context, state) => defaultPageBuilder( + context, + state, + const ActivityGenerator(), + ), + ), + ], + ), + ], + ), // Pangea# ShellRoute( pageBuilder: (context, state, child) => defaultPageBuilder( @@ -365,40 +389,6 @@ abstract class AppRoutes { : child, ), routes: [ - // #Pangea - GoRoute( - path: '/homepage', - redirect: loggedOutRedirect, - pageBuilder: (context, state) => defaultPageBuilder( - context, - state, - const SuggestionsPage(), - ), - routes: [ - ...newRoomRoutes, - GoRoute( - path: '/planner', - pageBuilder: (context, state) => defaultPageBuilder( - context, - state, - const ActivityPlannerPage(), - ), - redirect: loggedOutRedirect, - routes: [ - GoRoute( - path: '/generator', - redirect: loggedOutRedirect, - pageBuilder: (context, state) => defaultPageBuilder( - context, - state, - const ActivityGenerator(), - ), - ), - ], - ), - ], - ), - // Pangea# GoRoute( path: 'settings', pageBuilder: (context, state) => defaultPageBuilder( @@ -802,21 +792,14 @@ abstract class AppRoutes { ? TwoColumnLayout( mainView: ChatList( activeChat: state.pathParameters['roomid'], - // #Pangea activeSpaceId: state.uri.queryParameters['spaceId'], activeFilter: state.uri.queryParameters['filter'], - // Pangea# displayNavigationRail: state.path?.startsWith('/rooms/settings') != true, ), sideView: child, ) - : FluffyThemes.isColumnMode(context) || - (state.fullPath?.split("/").reversed.elementAt(1) == - 'rooms' && - state.pathParameters['roomid'] != null) - ? child - : BottomNavLayout(mainView: child), + : child, ); // Pangea# } diff --git a/lib/config/setting_keys.dart b/lib/config/setting_keys.dart index 9e82c6b38..8b7bae372 100644 --- a/lib/config/setting_keys.dart +++ b/lib/config/setting_keys.dart @@ -32,6 +32,10 @@ abstract class SettingKeys { 'chat.fluffy.swipeRightToLeftToReply'; static const String experimentalVoip = 'chat.fluffy.experimental_voip'; static const String showPresences = 'chat.fluffy.show_presences'; + // #Pangea + static const String displayNavigationRail = + 'chat.fluffy.display_navigation_rail'; + // Pangea# } enum AppSettings { diff --git a/lib/pages/chat_list/chat_list_body.dart b/lib/pages/chat_list/chat_list_body.dart index 39e08dab3..ec4280601 100644 --- a/lib/pages/chat_list/chat_list_body.dart +++ b/lib/pages/chat_list/chat_list_body.dart @@ -201,7 +201,8 @@ class ChatListViewBody extends StatelessWidget { // #Pangea // if (spaceDelegateCandidates.isNotEmpty && // !controller.widget.displayNavigationRail) - if (!controller.widget.displayNavigationRail) + if (!AppConfig.displayNavigationRail && + !FluffyThemes.isColumnMode(context)) // Pangea# ActiveFilter.spaces, ] diff --git a/lib/pages/chat_list/chat_list_view.dart b/lib/pages/chat_list/chat_list_view.dart index 35d5c07dc..f69d52840 100644 --- a/lib/pages/chat_list/chat_list_view.dart +++ b/lib/pages/chat_list/chat_list_view.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:go_router/go_router.dart'; +import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pangea/chat_list/widgets/chat_list_view_body_wrapper.dart'; @@ -31,8 +32,12 @@ class ChatListView extends StatelessWidget { }, child: Row( children: [ - if (FluffyThemes.isColumnMode(context) && - controller.widget.displayNavigationRail) ...[ + // #Pangea + // if (FluffyThemes.isColumnMode(context) && + // controller.widget.displayNavigationRail) ...[ + if (FluffyThemes.isColumnMode(context) || + AppConfig.displayNavigationRail) ...[ + // Pangea# SpacesNavigationRail( activeSpaceId: controller.activeSpaceId, onGoToChats: controller.clearActiveSpace, diff --git a/lib/pages/chat_list/navi_rail_item.dart b/lib/pages/chat_list/navi_rail_item.dart index 0e844e05d..6b4d3c540 100644 --- a/lib/pages/chat_list/navi_rail_item.dart +++ b/lib/pages/chat_list/navi_rail_item.dart @@ -44,7 +44,14 @@ class NaviRailItem extends StatelessWidget { bottom: 8, left: 0, child: AnimatedContainer( - width: isSelected ? 8 : 0, + // #Pangea + // width: isSelected ? 8 : 0, + width: isSelected + ? FluffyThemes.isColumnMode(context) + ? 8 + : 4 + : 0, + // Pangea# duration: FluffyThemes.animationDuration, curve: FluffyThemes.animationCurve, decoration: BoxDecoration( diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 24533cc31..879a57213 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -527,6 +527,18 @@ class _SpaceViewState extends State { final room = Matrix.of(context).client.getRoomById(widget.spaceId); final displayname = room?.getLocalizedDisplayname() ?? L10n.of(context).nothingFound; + + // #Pangea + final joinedParents = room?.spaceParents + .map((parent) { + final roomId = parent.roomId; + if (roomId == null) return null; + return room.client.getRoomById(roomId); + }) + .whereType() + .toList(); + // Pangea# + return Scaffold( // #Pangea // appBar: AppBar( @@ -539,14 +551,51 @@ class _SpaceViewState extends State { _onSpaceAction(SpaceActions.settings); }, child: AppBar( - // Pangea# - leading: FluffyThemes.isColumnMode(context) - ? null + // leading: FluffyThemes.isColumnMode(context) + // ? null + // : Center( + // child: CloseButton( + // onPressed: widget.onBack, + // ), + // ), + leading: joinedParents?.isEmpty ?? true + ? FluffyThemes.isColumnMode(context) + ? null + : Center( + child: CloseButton( + onPressed: widget.onBack, + ), + ) : Center( - child: CloseButton( - onPressed: widget.onBack, - ), + child: joinedParents!.length == 1 + ? IconButton( + icon: const Icon(Icons.arrow_back_outlined), + onPressed: () => + widget.toParentSpace(joinedParents.first.id), + ) + : PopupMenuButton( + popUpAnimationStyle: AnimationStyle( + duration: const Duration(milliseconds: 0), + ), + tooltip: null, + useRootNavigator: true, + icon: const Icon(Icons.arrow_back_outlined), + itemBuilder: (context) { + return [ + ...joinedParents.mapIndexed((i, room) { + return PopupMenuItem( + value: i, + child: Text(room.getLocalizedDisplayname()), + ); + }), + ]; + }, + onSelected: (i) { + widget.toParentSpace(joinedParents[i].id); + }, + ), ), + // Pangea# automaticallyImplyLeading: false, titleSpacing: FluffyThemes.isColumnMode(context) ? null : 0, title: ListTile( @@ -660,14 +709,16 @@ class _SpaceViewState extends State { // Pangea# .toList(); - final joinedParents = room.spaceParents - .map((parent) { - final roomId = parent.roomId; - if (roomId == null) return null; - return room.client.getRoomById(roomId); - }) - .whereType() - .toList(); + // #Pangea + // final joinedParents = room.spaceParents + // .map((parent) { + // final roomId = parent.roomId; + // if (roomId == null) return null; + // return room.client.getRoomById(roomId); + // }) + // .whereType() + // .toList(); + // Pangea# final filter = _filterController.text.trim().toLowerCase(); return CustomScrollView( slivers: [ @@ -715,51 +766,51 @@ class _SpaceViewState extends State { ), ), ), - SliverList.builder( - itemCount: joinedParents.length, - itemBuilder: (context, i) { - final displayname = - joinedParents[i].getLocalizedDisplayname(); - return Padding( - padding: const EdgeInsets.symmetric( - horizontal: 8, - vertical: 1, - ), - child: Material( - borderRadius: - BorderRadius.circular(AppConfig.borderRadius), - clipBehavior: Clip.hardEdge, - child: ListTile( - minVerticalPadding: 0, - leading: Icon( - Icons.adaptive.arrow_back_outlined, - size: 16, - ), - title: Row( - children: [ - Avatar( - mxContent: joinedParents[i].avatar, - name: displayname, - // #Pangea - userId: joinedParents[i].directChatMatrixID, - // Pangea# - size: Avatar.defaultSize / 2, - borderRadius: BorderRadius.circular( - AppConfig.borderRadius / 4, - ), - ), - const SizedBox(width: 8), - Expanded(child: Text(displayname)), - ], - ), - onTap: () => - widget.toParentSpace(joinedParents[i].id), - ), - ), - ); - }, - ), // #Pangea + // SliverList.builder( + // itemCount: joinedParents.length, + // itemBuilder: (context, i) { + // final displayname = + // joinedParents[i].getLocalizedDisplayname(); + // return Padding( + // padding: const EdgeInsets.symmetric( + // horizontal: 8, + // vertical: 1, + // ), + // child: Material( + // borderRadius: + // BorderRadius.circular(AppConfig.borderRadius), + // clipBehavior: Clip.hardEdge, + // child: ListTile( + // minVerticalPadding: 0, + // leading: Icon( + // Icons.adaptive.arrow_back_outlined, + // size: 16, + // ), + // title: Row( + // children: [ + // Avatar( + // mxContent: joinedParents[i].avatar, + // name: displayname, + // // #Pangea + // userId: joinedParents[i].directChatMatrixID, + // // Pangea# + // size: Avatar.defaultSize / 2, + // borderRadius: BorderRadius.circular( + // AppConfig.borderRadius / 4, + // ), + // ), + // const SizedBox(width: 8), + // Expanded(child: Text(displayname)), + // ], + // ), + // onTap: () => + // widget.toParentSpace(joinedParents[i].id), + // ), + // ), + // ); + // }, + // ), KnockingUsersIndicator(room: room), // Pangea# SliverList.builder( diff --git a/lib/pages/settings/settings_view.dart b/lib/pages/settings/settings_view.dart index a912fd401..4c51ea86d 100644 --- a/lib/pages/settings/settings_view.dart +++ b/lib/pages/settings/settings_view.dart @@ -41,7 +41,11 @@ class SettingsView extends StatelessWidget { // Pangea# return Row( children: [ - if (FluffyThemes.isColumnMode(context)) ...[ + // #Pangea + // if (FluffyThemes.isColumnMode(context)) ...[ + if (FluffyThemes.isColumnMode(context) || + AppConfig.displayNavigationRail) ...[ + // Pangea# SpacesNavigationRail( activeSpaceId: null, onGoToChats: () => context.go('/rooms'), diff --git a/lib/pages/settings_style/settings_style_view.dart b/lib/pages/settings_style/settings_style_view.dart index d234759df..05bde2f42 100644 --- a/lib/pages/settings_style/settings_style_view.dart +++ b/lib/pages/settings_style/settings_style_view.dart @@ -359,6 +359,14 @@ class SettingsStyleView extends StatelessWidget { storeKey: SettingKeys.separateChatTypes, defaultValue: AppConfig.separateChatTypes, ), + // #Pangea + // SettingsSwitchListTile.adaptive( + // title: L10n.of(context).displayNavigationRail, + // onChanged: (b) => AppConfig.displayNavigationRail = b, + // storeKey: SettingKeys.displayNavigationRail, + // defaultValue: AppConfig.displayNavigationRail, + // ), + // Pangea# ], ), ), diff --git a/lib/pangea/activity_suggestions/suggestions_page.dart b/lib/pangea/activity_suggestions/suggestions_page.dart index 45beaaf97..e46be8e91 100644 --- a/lib/pangea/activity_suggestions/suggestions_page.dart +++ b/lib/pangea/activity_suggestions/suggestions_page.dart @@ -1,9 +1,13 @@ import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pangea/activity_suggestions/activity_suggestions_area.dart'; import 'package:fluffychat/pangea/analytics_summary/learning_progress_indicators.dart'; import 'package:fluffychat/pangea/public_spaces/public_spaces_area.dart'; +import 'package:fluffychat/widgets/navigation_rail.dart'; class SuggestionsPage extends StatelessWidget { const SuggestionsPage({super.key}); @@ -11,24 +15,45 @@ class SuggestionsPage extends StatelessWidget { @override Widget build(BuildContext context) { final isColumnMode = FluffyThemes.isColumnMode(context); - return SafeArea( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 24.0, - vertical: 16.0, - ), - child: Column( - spacing: 24.0, - children: [ - if (!isColumnMode) const LearningProgressIndicators(), - const ActivitySuggestionsArea( - showTitle: true, - scrollDirection: Axis.horizontal, + return Material( + child: SafeArea( + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (!isColumnMode && AppConfig.displayNavigationRail) ...[ + SpacesNavigationRail( + activeSpaceId: null, + onGoToChats: () => context.go('/rooms'), + onGoToSpaceId: (spaceId) => + context.go('/rooms?spaceId=$spaceId'), + ), + Container( + color: Theme.of(context).dividerColor, + width: 1, ), - const PublicSpacesArea(), ], - ), + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 24.0, + vertical: 16.0, + ), + child: Column( + spacing: 24.0, + children: [ + if (!isColumnMode) const LearningProgressIndicators(), + const ActivitySuggestionsArea( + showTitle: true, + scrollDirection: Axis.horizontal, + ), + const PublicSpacesArea(), + ], + ), + ), + ), + ), + ], ), ), ); diff --git a/lib/pangea/analytics_summary/learning_progress_indicators.dart b/lib/pangea/analytics_summary/learning_progress_indicators.dart index ac28bc546..440a8a805 100644 --- a/lib/pangea/analytics_summary/learning_progress_indicators.dart +++ b/lib/pangea/analytics_summary/learning_progress_indicators.dart @@ -105,147 +105,156 @@ class LearningProgressIndicatorsState final mxid = client.userID ?? L10n.of(context).user; final displayname = _profile?.displayName ?? mxid.localpart ?? mxid; - return Row( - children: [ - Tooltip( - message: L10n.of(context).settings, - child: MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - onTap: () => context.go("/rooms/settings"), - child: Padding( - padding: const EdgeInsets.only( - bottom: 8.0, - right: 8.0, - ), - child: Stack( - clipBehavior: Clip.none, // Allow overflow - children: [ - FutureBuilder( - future: client.fetchOwnProfile(), - builder: (context, snapshot) => Stack( - alignment: Alignment.center, - children: [ - Material( - color: Colors.transparent, - borderRadius: BorderRadius.circular(99), - child: Avatar( - mxContent: snapshot.data?.avatarUrl, - name: snapshot.data?.displayName ?? - client.userID!.localpart, - size: 60, - ), - ), - ], - ), - ), - Positioned( - bottom: -3, - right: -3, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - color: Theme.of(context).colorScheme.surfaceBright, - ), - padding: const EdgeInsets.all(4.0), - child: Icon( - size: 14, - Icons.settings_outlined, - color: Theme.of(context).colorScheme.primary, - weight: 1000, - ), - ), - ), - ], - ), - ), - ), - ), - ), - const SizedBox(width: 10), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - spacing: 6.0, - children: [ - Text( - displayname, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.primary, - ), - ), - LearningSettingsButton( - onTap: () => showDialog( - context: context, - builder: (c) => const SettingsLearning(), - barrierDismissible: false, - ), - l2: userL2?.langCode.toUpperCase(), - ), - ], - ), - const SizedBox(height: 6), - Row( - spacing: 6.0, - children: ConstructTypeEnum.values - .map( - (c) => ProgressIndicatorBadge( - points: uniqueLemmas(c.indicator), - loading: _loading, - onTap: () { - showDialog( - context: context, - builder: (context) => AnalyticsPopupWrapper( - view: c, - ), - ); - }, - indicator: c.indicator, - ), - ) - .toList(), - ), - const SizedBox(height: 6), - MouseRegion( + return LayoutBuilder( + builder: (context, constraints) { + return Row( + children: [ + Tooltip( + message: L10n.of(context).settings, + child: MouseRegion( cursor: SystemMouseCursors.click, child: GestureDetector( - onTap: () { - showDialog( - context: context, - builder: (c) => const LevelBarPopup(), - ); - }, - child: SizedBox( - height: 26, + onTap: () => context.go("/rooms/settings"), + child: Padding( + padding: const EdgeInsets.only( + bottom: 8.0, + right: 8.0, + ), child: Stack( - alignment: Alignment.center, + clipBehavior: Clip.none, // Allow overflow children: [ - Positioned( - left: 16, - right: 0, - child: LearningProgressBar( - level: _constructsModel.level, - totalXP: _constructsModel.totalXP, + FutureBuilder( + future: client.fetchOwnProfile(), + builder: (context, snapshot) => Stack( + alignment: Alignment.center, + children: [ + Material( + color: Colors.transparent, + borderRadius: BorderRadius.circular(99), + child: Avatar( + mxContent: snapshot.data?.avatarUrl, + name: snapshot.data?.displayName ?? + client.userID!.localpart, + size: 60, + ), + ), + ], ), ), Positioned( - left: 0, - child: LevelBadge(level: _constructsModel.level), + bottom: -3, + right: -3, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + color: + Theme.of(context).colorScheme.surfaceBright, + ), + padding: const EdgeInsets.all(4.0), + child: Icon( + size: 14, + Icons.settings_outlined, + color: Theme.of(context).colorScheme.primary, + weight: 1000, + ), + ), ), ], ), ), ), ), - ], - ), - ), - ], + ), + const SizedBox(width: 10), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + spacing: 6.0, + children: [ + Text( + displayname, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + color: Theme.of(context).colorScheme.primary, + ), + ), + LearningSettingsButton( + onTap: () => showDialog( + context: context, + builder: (c) => const SettingsLearning(), + barrierDismissible: false, + ), + l2: userL2?.langCode.toUpperCase(), + ), + ], + ), + const SizedBox(height: 6), + Row( + spacing: 6.0, + children: ConstructTypeEnum.values + .map( + (c) => ProgressIndicatorBadge( + points: uniqueLemmas(c.indicator), + loading: _loading, + onTap: () { + showDialog( + context: context, + builder: (context) => AnalyticsPopupWrapper( + view: c, + ), + ); + }, + indicator: c.indicator, + mini: constraints.maxWidth < 380, + ), + ) + .toList(), + ), + const SizedBox(height: 6), + MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: () { + showDialog( + context: context, + builder: (c) => const LevelBarPopup(), + ); + }, + child: SizedBox( + height: 26, + child: Stack( + alignment: Alignment.center, + children: [ + Positioned( + left: 16, + right: 0, + child: LearningProgressBar( + level: _constructsModel.level, + totalXP: _constructsModel.totalXP, + ), + ), + Positioned( + left: 0, + child: LevelBadge( + level: _constructsModel.level, + mini: constraints.maxWidth < 380, + ), + ), + ], + ), + ), + ), + ), + ], + ), + ), + ], + ); + }, ); } } diff --git a/lib/pangea/analytics_summary/level_badge.dart b/lib/pangea/analytics_summary/level_badge.dart index 1282c1c41..805f7518c 100644 --- a/lib/pangea/analytics_summary/level_badge.dart +++ b/lib/pangea/analytics_summary/level_badge.dart @@ -8,8 +8,11 @@ import 'package:fluffychat/pangea/common/widgets/pressable_button.dart'; class LevelBadge extends StatelessWidget { final int level; + final bool mini; + const LevelBadge({ required this.level, + this.mini = false, super.key, }); @@ -46,7 +49,7 @@ class LevelBadge extends StatelessWidget { ), const SizedBox(width: 4), Text( - L10n.of(context).levelShort(level), + mini ? "$level" : L10n.of(context).levelShort(level), style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, diff --git a/lib/pangea/analytics_summary/progress_indicator.dart b/lib/pangea/analytics_summary/progress_indicator.dart index faaaa46b6..aa99cf40d 100644 --- a/lib/pangea/analytics_summary/progress_indicator.dart +++ b/lib/pangea/analytics_summary/progress_indicator.dart @@ -9,6 +9,7 @@ class ProgressIndicatorBadge extends StatelessWidget { final int points; final VoidCallback onTap; final ProgressIndicatorEnum indicator; + final bool mini; const ProgressIndicatorBadge({ super.key, @@ -16,6 +17,7 @@ class ProgressIndicatorBadge extends StatelessWidget { required this.indicator, required this.loading, required this.points, + this.mini = false, }); @override @@ -42,15 +44,17 @@ class ProgressIndicatorBadge extends StatelessWidget { color: indicator.color(context), weight: 1000, ), - const SizedBox(width: 4.0), - Text( - indicator.tooltip(context), - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.bold, - color: indicator.color(context), + if (!mini) ...[ + const SizedBox(width: 4.0), + Text( + indicator.tooltip(context), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + color: indicator.color(context), + ), ), - ), + ], const SizedBox(width: 4.0), !loading ? Text( diff --git a/lib/pangea/layouts/bottom_nav_layout.dart b/lib/pangea/layouts/bottom_nav_layout.dart deleted file mode 100644 index 3332a673d..000000000 --- a/lib/pangea/layouts/bottom_nav_layout.dart +++ /dev/null @@ -1,96 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:go_router/go_router.dart'; - -class BottomNavLayout extends StatelessWidget { - final Widget mainView; - - const BottomNavLayout({ - super.key, - required this.mainView, - }); - @override - Widget build(BuildContext context) { - return Scaffold( - body: mainView, - bottomNavigationBar: const BottomNavBar(), - ); - } -} - -class BottomNavBar extends StatefulWidget { - const BottomNavBar({ - super.key, - }); - - @override - BottomNavBarState createState() => BottomNavBarState(); -} - -class BottomNavBarState extends State { - int get selectedIndex { - final route = GoRouterState.of(context).fullPath.toString(); - if (route.contains("settings")) { - return 2; - } - if (route.contains('homepage')) { - return 0; - } - return 1; - } - - void onItemTapped(int index) { - switch (index) { - case 0: - context.go('/rooms/homepage'); - break; - case 1: - context.go('/rooms'); - break; - case 2: - context.go('/rooms/settings'); - break; - } - - if (mounted) setState(() {}); - } - - @override - Widget build(BuildContext context) { - return Container( - decoration: BoxDecoration( - border: Border( - top: BorderSide( - color: Theme.of(context).colorScheme.primary.withAlpha(50), - ), - ), - ), - child: BottomNavigationBar( - iconSize: 16.0, - onTap: onItemTapped, - selectedItemColor: Theme.of(context).colorScheme.primary, - selectedFontSize: 14.0, - unselectedFontSize: 14.0, - currentIndex: selectedIndex, - items: [ - BottomNavigationBarItem( - icon: const Icon(Icons.home_outlined), - activeIcon: const Icon(Icons.home), - label: L10n.of(context).home, - ), - BottomNavigationBarItem( - icon: const Icon(Icons.chat_bubble_outline), - activeIcon: const Icon(Icons.chat_bubble), - label: L10n.of(context).chats, - ), - BottomNavigationBarItem( - icon: const Icon(Icons.settings_outlined), - activeIcon: const Icon(Icons.settings), - label: L10n.of(context).settings, - ), - ], - ), - ); - } -} diff --git a/lib/widgets/matrix.dart b/lib/widgets/matrix.dart index 7c071fbc6..1dea15a8d 100644 --- a/lib/widgets/matrix.dart +++ b/lib/widgets/matrix.dart @@ -484,6 +484,12 @@ class MatrixState extends State with WidgetsBindingObserver { AppConfig.showPresences = store.getBool(SettingKeys.showPresences) ?? AppConfig.showPresences; + + // #Pangea + AppConfig.displayNavigationRail = + store.getBool(SettingKeys.displayNavigationRail) ?? + AppConfig.displayNavigationRail; + // Pangea# } @override diff --git a/lib/widgets/navigation_rail.dart b/lib/widgets/navigation_rail.dart index d3def0630..3e04d61b9 100644 --- a/lib/widgets/navigation_rail.dart +++ b/lib/widgets/navigation_rail.dart @@ -34,6 +34,14 @@ class SpacesNavigationRail extends StatelessWidget { .uri .path .startsWith('/rooms/settings'); + // #Pangea + final isHomepage = GoRouter.of(context) + .routeInformationProvider + .value + .uri + .path + .contains('homepage'); + // Pangea# return StreamBuilder( key: ValueKey( client.userID.toString(), @@ -53,7 +61,12 @@ class SpacesNavigationRail extends StatelessWidget { .toList(); return SizedBox( - width: FluffyThemes.navRailWidth, + // #Pangea + // width: FluffyThemes.navRailWidth, + width: FluffyThemes.isColumnMode(context) + ? FluffyThemes.navRailWidth + : FluffyThemes.navRailWidth * 0.75, + // Pangea# child: Column( children: [ Expanded( @@ -61,31 +74,45 @@ class SpacesNavigationRail extends StatelessWidget { scrollDirection: Axis.vertical, // #Pangea // itemCount: rootSpaces.length + 2, - itemCount: rootSpaces.length + 3, + itemCount: rootSpaces.length + 4, // Pangea# itemBuilder: (context, i) { + // #Pangea if (i == 0) { return NaviRailItem( - isSelected: activeSpaceId == null && !isSettings, - onTap: onGoToChats, + isSelected: isHomepage, + onTap: () => context.go("/rooms/homepage"), icon: const Padding( padding: EdgeInsets.all(10.0), - // #Pangea - // child: Icon(Icons.forum_outlined), child: Icon(Icons.home_outlined), - // Pangea# ), selectedIcon: const Padding( padding: EdgeInsets.all(10.0), - // #Pangea - // child: Icon(Icons.forum), child: Icon(Icons.home), - // Pangea# ), - // #Pangea - // toolTip: L10n.of(context).chats, toolTip: L10n.of(context).home, + unreadBadgeFilter: (room) => true, + ); + } + i--; + // Pangea# + if (i == 0) { + return NaviRailItem( + // #Pangea + // isSelected: activeSpaceId == null && !isSettings, + isSelected: + activeSpaceId == null && !isSettings && !isHomepage, // Pangea# + onTap: onGoToChats, + icon: const Padding( + padding: EdgeInsets.all(10.0), + child: Icon(Icons.forum_outlined), + ), + selectedIcon: const Padding( + padding: EdgeInsets.all(10.0), + child: Icon(Icons.forum), + ), + toolTip: L10n.of(context).chats, unreadBadgeFilter: (room) => true, ); }