updates to main menu design

pull/1476/head
ggurdin 1 year ago
parent 5528ba70db
commit 0a627ef856
No known key found for this signature in database
GPG Key ID: A01CB41737CBB478

@ -1,11 +1,11 @@
import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pages/chat_list/chat_list.dart';
import 'package:fluffychat/pages/chat_list/chat_list_header.dart';
import 'package:fluffychat/pages/chat_list/chat_list_item.dart'; import 'package:fluffychat/pages/chat_list/chat_list_item.dart';
import 'package:fluffychat/pages/chat_list/dummy_chat_list_item.dart'; import 'package:fluffychat/pages/chat_list/dummy_chat_list_item.dart';
import 'package:fluffychat/pages/chat_list/search_title.dart'; import 'package:fluffychat/pages/chat_list/search_title.dart';
import 'package:fluffychat/pages/chat_list/space_view.dart'; import 'package:fluffychat/pages/chat_list/space_view.dart';
import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart'; import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart';
import 'package:fluffychat/pangea/widgets/chat_list/pangea_chat_list_header.dart';
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
import 'package:fluffychat/utils/stream_extension.dart'; import 'package:fluffychat/utils/stream_extension.dart';
import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/avatar.dart';
@ -78,7 +78,10 @@ class ChatListViewBody extends StatelessWidget {
child: CustomScrollView( child: CustomScrollView(
controller: controller.scrollController, controller: controller.scrollController,
slivers: [ slivers: [
ChatListHeader(controller: controller), // #Pangea
// ChatListHeader(controller: controller),
PangeaChatListHeader(controller: controller),
// Pangea#
SliverList( SliverList(
delegate: SliverChildListDelegate( delegate: SliverChildListDelegate(
[ [

@ -107,9 +107,13 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget {
), ),
) )
// #Pangea // #Pangea
: SizedBox( : const SizedBox(
width: 0, width: 0,
child: ClientChooserButton(controller), child: ClientChooserButton(
// #Pangea
// controller
// Pangea#
),
) )
// : TextButton.icon( // : TextButton.icon(
// onPressed: controller.setServer, // onPressed: controller.setServer,
@ -127,9 +131,13 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget {
// ), // ),
// ) // )
// Pangea# // Pangea#
: SizedBox( : const SizedBox(
width: 0, width: 0,
child: ClientChooserButton(controller), child: ClientChooserButton(
// #Pangea
// controller
// Pangea#
),
), ),
), ),
), ),

@ -11,12 +11,18 @@ import 'package:go_router/go_router.dart';
// import 'package:keyboard_shortcuts/keyboard_shortcuts.dart'; // import 'package:keyboard_shortcuts/keyboard_shortcuts.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
import 'chat_list.dart';
class ClientChooserButton extends StatelessWidget { class ClientChooserButton extends StatelessWidget {
final ChatListController controller; // #Pangea
// final ChatListController controller;
// Pangea#
const ClientChooserButton(this.controller, {super.key}); const ClientChooserButton(
// #Pangea
// this.controller,
// Pangea#
{
super.key,
});
List<PopupMenuEntry<Object>> _bundleMenuItems(BuildContext context) { List<PopupMenuEntry<Object>> _bundleMenuItems(BuildContext context) {
final matrix = Matrix.of(context); final matrix = Matrix.of(context);
@ -268,12 +274,27 @@ class ClientChooserButton extends StatelessWidget {
child: Material( child: Material(
color: Colors.transparent, color: Colors.transparent,
borderRadius: BorderRadius.circular(99), borderRadius: BorderRadius.circular(99),
child: Avatar( child:
mxContent: snapshot.data?.avatarUrl, // #Pangea
name: snapshot.data?.displayName ?? Stack(
matrix.client.userID!.localpart, alignment: Alignment.bottomRight,
size: 32, children: [
Padding(
padding: const EdgeInsets.all(4),
child:
// Pangea#
Avatar(
mxContent: snapshot.data?.avatarUrl,
name: snapshot.data?.displayName ??
matrix.client.userID!.localpart,
size: 50,
),
// #Pangea
),
const Icon(Icons.settings_outlined, size: 20),
],
), ),
// Pangea#
), ),
), ),
], ],
@ -296,11 +317,14 @@ class ClientChooserButton extends StatelessWidget {
Object object, Object object,
BuildContext context, BuildContext context,
) async { ) async {
if (object is Client) { // #Pangea
controller.setActiveClient(object); // if (object is Client) {
} else if (object is String) { // controller.setActiveClient(object);
controller.setActiveBundle(object); // } else if (object is String) {
} else if (object is SettingsAction) { // controller.setActiveBundle(object);
// } else
// Pangea#
if (object is SettingsAction) {
switch (object) { switch (object) {
case SettingsAction.addAccount: case SettingsAction.addAccount:
final consent = await showOkCancelAlertDialog( final consent = await showOkCancelAlertDialog(
@ -319,7 +343,10 @@ class ClientChooserButton extends StatelessWidget {
// break; // break;
// Pangea# // Pangea#
case SettingsAction.newSpace: case SettingsAction.newSpace:
controller.createNewSpace(); // #Pangea
// controller.createNewSpace();
context.push<String?>('/rooms/newspace');
// Pangea#
break; break;
// #Pangea // #Pangea
// case SettingsAction.invite: // case SettingsAction.invite:

@ -19,12 +19,14 @@ class LevelBar extends StatefulWidget {
class LevelBarState extends State<LevelBar> { class LevelBarState extends State<LevelBar> {
double prevWidth = 0; double prevWidth = 0;
double get width =>
widget.progressBarDetails.totalWidth * widget.details.widthMultiplier;
@override @override
void didUpdateWidget(covariant LevelBar oldWidget) { void didUpdateWidget(covariant LevelBar oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
if (oldWidget.details.currentPoints != widget.details.currentPoints) { if (oldWidget.details.currentPoints != widget.details.currentPoints) {
setState(() => prevWidth = widget.details.width); setState(() => prevWidth = width);
} }
} }
@ -33,7 +35,7 @@ class LevelBarState extends State<LevelBar> {
return AnimatedLevelBar( return AnimatedLevelBar(
height: widget.progressBarDetails.height, height: widget.progressBarDetails.height,
beginWidth: prevWidth, beginWidth: prevWidth,
endWidth: widget.details.width, endWidth: width,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: const BorderRadius.all( borderRadius: const BorderRadius.all(
Radius.circular(AppConfig.borderRadius), Radius.circular(AppConfig.borderRadius),

@ -6,31 +6,55 @@ import 'package:flutter/material.dart';
// Provide an order list of level indicators, each with it's color // Provide an order list of level indicators, each with it's color
// and stream. Also provide an overall width and pointsPerLevel. // and stream. Also provide an overall width and pointsPerLevel.
class ProgressBar extends StatelessWidget { class ProgressBar extends StatefulWidget {
final List<LevelBarDetails> levelBars; final List<LevelBarDetails> levelBars;
final ProgressBarDetails progressBarDetails;
const ProgressBar({ const ProgressBar({
super.key, super.key,
required this.levelBars, required this.levelBars,
required this.progressBarDetails,
}); });
@override
ProgressBarState createState() => ProgressBarState();
}
class ProgressBarState extends State<ProgressBar> {
double width = 0;
void setWidth(double newWidth) {
if (width != newWidth) {
setState(() => width = newWidth);
}
}
get progressBarDetails => ProgressBarDetails(
totalWidth: width,
borderColor: Theme.of(context).colorScheme.primary.withOpacity(0.5),
);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Stack( return LayoutBuilder(
alignment: Alignment.centerLeft, builder: (context, constraints) {
children: [ if (width != constraints.maxWidth) {
ProgressBarBackground(details: progressBarDetails), WidgetsBinding.instance.addPostFrameCallback(
for (final levelBar in levelBars) (_) => setWidth(constraints.maxWidth),
Padding( );
padding: const EdgeInsets.symmetric(horizontal: 2), }
child: LevelBar( return Stack(
details: levelBar, alignment: Alignment.centerLeft,
progressBarDetails: progressBarDetails, children: [
), ProgressBarBackground(details: progressBarDetails),
), for (final levelBar in widget.levelBars)
], Padding(
padding: const EdgeInsets.symmetric(horizontal: 2),
child: LevelBar(
details: levelBar,
progressBarDetails: progressBarDetails,
),
),
],
);
},
); );
} }
} }

@ -3,12 +3,12 @@ import 'dart:ui';
class LevelBarDetails { class LevelBarDetails {
final Color fillColor; final Color fillColor;
final int currentPoints; final int currentPoints;
final double width; final double widthMultiplier;
const LevelBarDetails({ const LevelBarDetails({
required this.fillColor, required this.fillColor,
required this.currentPoints, required this.currentPoints,
required this.width, required this.widthMultiplier,
}); });
} }

@ -1,22 +1,21 @@
import 'dart:async'; import 'dart:async';
import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat_list/client_chooser_button.dart';
import 'package:fluffychat/pangea/controllers/get_analytics_controller.dart'; import 'package:fluffychat/pangea/controllers/get_analytics_controller.dart';
import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/enum/construct_type_enum.dart'; import 'package:fluffychat/pangea/enum/construct_type_enum.dart';
import 'package:fluffychat/pangea/enum/progress_indicators_enum.dart'; import 'package:fluffychat/pangea/enum/progress_indicators_enum.dart';
import 'package:fluffychat/pangea/models/analytics/construct_list_model.dart'; import 'package:fluffychat/pangea/models/analytics/construct_list_model.dart';
import 'package:fluffychat/pangea/models/analytics/constructs_model.dart'; import 'package:fluffychat/pangea/models/analytics/constructs_model.dart';
import 'package:fluffychat/pangea/pages/settings_learning/settings_learning.dart';
import 'package:fluffychat/pangea/widgets/animations/progress_bar/progress_bar.dart'; import 'package:fluffychat/pangea/widgets/animations/progress_bar/progress_bar.dart';
import 'package:fluffychat/pangea/widgets/animations/progress_bar/progress_bar_details.dart'; import 'package:fluffychat/pangea/widgets/animations/progress_bar/progress_bar_details.dart';
import 'package:fluffychat/pangea/widgets/chat_list/analytics_summary/analytics_popup.dart'; import 'package:fluffychat/pangea/widgets/chat_list/analytics_summary/analytics_popup.dart';
import 'package:fluffychat/pangea/widgets/chat_list/analytics_summary/progress_indicator.dart'; import 'package:fluffychat/pangea/widgets/chat_list/analytics_summary/progress_indicator.dart';
import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/pangea/widgets/flag.dart';
import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
/// A summary of "My Analytics" shown at the top of the chat list /// A summary of "My Analytics" shown at the top of the chat list
/// It shows a variety of progress indicators such as /// It shows a variety of progress indicators such as
@ -120,7 +119,7 @@ class LearningProgressIndicatorsState
} }
} }
double get levelBarWidth => FluffyThemes.columnWidth - (32 * 2) - 25; // double get levelBarWidth => FluffyThemes.columnWidth - (32 * 2) - 25;
Color levelColor(int level) { Color levelColor(int level) {
final colors = [ final colors = [
@ -147,19 +146,14 @@ class LearningProgressIndicatorsState
? const Color.fromARGB(255, 0, 190, 83) ? const Color.fromARGB(255, 0, 190, 83)
: Theme.of(context).colorScheme.primary, : Theme.of(context).colorScheme.primary,
currentPoints: currentXP, currentPoints: currentXP,
width: levelBarWidth * _pangeaController.analytics.levelProgress, widthMultiplier: _pangeaController.analytics.levelProgress,
), ),
LevelBarDetails( LevelBarDetails(
fillColor: Theme.of(context).colorScheme.primary, fillColor: Theme.of(context).colorScheme.primary,
currentPoints: serverXP, currentPoints: serverXP,
width: widthMultiplier: _pangeaController.analytics.serverLevelProgress,
levelBarWidth * _pangeaController.analytics.serverLevelProgress,
), ),
], ],
progressBarDetails: ProgressBarDetails(
totalWidth: levelBarWidth,
borderColor: Theme.of(context).colorScheme.primary.withOpacity(0.5),
),
); );
final levelBadge = Container( final levelBadge = Container(
@ -184,84 +178,67 @@ class LearningProgressIndicatorsState
), ),
); );
return Stack( return Row(
alignment: Alignment.topCenter,
children: [ children: [
// const Positioned( const ClientChooserButton(),
// child: PointsGainedAnimation(), const SizedBox(width: 6),
// ), Expanded(
Column( child: Column(
mainAxisSize: MainAxisSize.min, children: [
children: [ Row(
Padding(
padding: const EdgeInsets.fromLTRB(46, 0, 32, 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
FutureBuilder(
future: _pangeaController.matrixState.client
.getProfileFromUserId(
_pangeaController.matrixState.client.userID!,
),
builder: (context, snapshot) {
final mxid = Matrix.of(context).client.userID ??
L10n.of(context)!.user;
return Avatar(
name: snapshot.data?.displayName ??
mxid.localpart ??
mxid,
mxContent: snapshot.data?.avatarUrl,
size: 40,
);
},
),
Row( Row(
mainAxisAlignment: MainAxisAlignment.center,
children: ProgressIndicatorEnum.values children: ProgressIndicatorEnum.values
.where( .where((i) => i != ProgressIndicatorEnum.level)
(indicator) =>
indicator != ProgressIndicatorEnum.level,
)
.map( .map(
(indicator) => ProgressIndicatorBadge( (indicator) => Padding(
points: getProgressPoints(indicator), padding: const EdgeInsets.only(right: 10),
onTap: () { child: ProgressIndicatorBadge(
final model = getConstructsModel(indicator); points: getProgressPoints(indicator),
if (model == null) return; onTap: () {
showDialog<AnalyticsPopup>( final model = getConstructsModel(indicator);
context: context, if (model == null) return;
builder: (c) => AnalyticsPopup( showDialog<AnalyticsPopup>(
indicator: indicator, context: context,
constructsModel: model, builder: (c) => AnalyticsPopup(
), indicator: indicator,
); constructsModel: model,
}, ),
progressIndicator: indicator, );
loading: loading, },
progressIndicator: indicator,
loading: loading,
),
), ),
) )
.toList(), .toList(),
), ),
InkWell(
onTap: () => showDialog(
context: context,
builder: (c) => const SettingsLearning(),
),
child: LanguageFlag(
language: _pangeaController.languageController.userL2,
size: 24,
),
),
], ],
), ),
), const SizedBox(height: 6),
Center( SizedBox(
child: SizedBox(
height: 36, height: 36,
child: SizedBox( child: Stack(
width: levelBarWidth + 16, alignment: Alignment.center,
child: Stack( children: [
alignment: Alignment.center, Positioned(left: 16, right: 0, child: progressBar),
children: [ Positioned(left: 0, child: levelBadge),
Positioned(left: 16, right: 0, child: progressBar), ],
Positioned(left: 0, child: levelBadge),
],
),
), ),
), ),
), ],
const SizedBox(height: 16), ),
],
), ),
], ],
); );

@ -18,40 +18,34 @@ class ProgressIndicatorBadge extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Tooltip(
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5), message: progressIndicator.tooltip(context),
child: Tooltip( child: InkWell(
message: progressIndicator.tooltip(context), onTap: onTap,
child: InkWell( child: Row(
onTap: onTap, mainAxisSize: MainAxisSize.min,
child: Padding( children: [
padding: const EdgeInsets.symmetric(horizontal: 4), Icon(
child: Row( progressIndicator.icon,
mainAxisSize: MainAxisSize.min, color: progressIndicator.color(context),
children: [
Icon(
progressIndicator.icon,
color: progressIndicator.color(context),
),
const SizedBox(width: 5),
!loading
? Text(
points?.toString() ?? '0',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
)
: const SizedBox(
height: 8,
width: 8,
child: CircularProgressIndicator.adaptive(
strokeWidth: 2,
),
),
],
), ),
), const SizedBox(width: 5),
!loading
? Text(
points?.toString() ?? '0',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
)
: const SizedBox(
height: 8,
width: 8,
child: CircularProgressIndicator.adaptive(
strokeWidth: 2,
),
),
],
), ),
), ),
); );

@ -0,0 +1,82 @@
import 'package:fluffychat/pages/chat_list/chat_list.dart';
import 'package:fluffychat/pangea/widgets/chat_list/analytics_summary/learning_progress_indicators.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
class PangeaChatListHeader extends StatelessWidget
implements PreferredSizeWidget {
final ChatListController controller;
final bool globalSearch;
const PangeaChatListHeader({
super.key,
required this.controller,
this.globalSearch = true,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return SliverList(
delegate: SliverChildListDelegate(
[
Padding(
padding: const EdgeInsets.only(
top: 16,
left: 16,
right: 16,
),
child: Column(
children: [
const LearningProgressIndicators(),
const SizedBox(height: 16),
TextField(
controller: controller.searchController,
focusNode: controller.searchFocusNode,
textInputAction: TextInputAction.search,
onChanged: (text) => controller.onSearchEnter(
text,
globalSearch: globalSearch,
),
decoration: InputDecoration(
filled: true,
fillColor: theme.colorScheme.secondaryContainer,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(99),
),
contentPadding: EdgeInsets.zero,
hintText: L10n.of(context)!.searchChatsRooms,
hintStyle: TextStyle(
color: theme.colorScheme.onPrimaryContainer,
fontWeight: FontWeight.normal,
),
floatingLabelBehavior: FloatingLabelBehavior.never,
prefixIcon: controller.isSearchMode
? IconButton(
tooltip: L10n.of(context)!.cancel,
icon: const Icon(Icons.close_outlined),
onPressed: controller.cancelSearch,
color: theme.colorScheme.onPrimaryContainer,
)
: IconButton(
onPressed: controller.startSearch,
icon: Icon(
Icons.search_outlined,
color: theme.colorScheme.onPrimaryContainer,
),
),
),
),
],
),
),
],
),
);
}
@override
Size get preferredSize => const Size.fromHeight(56);
}
Loading…
Cancel
Save