rough draft of navigation menu design updates (#947)

pull/1544/head
ggurdin 12 months ago committed by GitHub
parent f9488cae01
commit 5f547deb58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -4498,6 +4498,13 @@
"selectBotChatMode": "Select chat mode", "selectBotChatMode": "Select chat mode",
"messageNotInTargetLang": "Message not in target language", "messageNotInTargetLang": "Message not in target language",
"other": "Other", "other": "Other",
"levelShort": "LVL {level}",
"@levelShort": {
"type": "text",
"placeholders": {
"level": {}
}
},
"botModeValidation": "Please select a chat mode", "botModeValidation": "Please select a chat mode",
"clickBestOption": "Choose the best options to translate your message!", "clickBestOption": "Choose the best options to translate your message!",
"unlockedLanguageTools": "Youve unlocked the language tools for this message. Try them out by clicking below!", "unlockedLanguageTools": "Youve unlocked the language tools for this message. Try them out by clicking below!",

@ -35,6 +35,8 @@ abstract class AppConfig {
static const Color activeToggleColor = Color(0xFF33D057); static const Color activeToggleColor = Color(0xFF33D057);
static const Color success = Color(0xFF33D057); static const Color success = Color(0xFF33D057);
static const Color warning = Color.fromARGB(255, 210, 124, 12); static const Color warning = Color.fromARGB(255, 210, 124, 12);
static const Color gold = Color.fromARGB(255, 253, 191, 1);
static const Color goldLight = Color.fromARGB(255, 254, 223, 73);
static const int overlayAnimationDuration = 250; static const int overlayAnimationDuration = 250;
// static String _privacyUrl = // static String _privacyUrl =
// 'https://gitlab.com/famedly/fluffychat/-/blob/main/PRIVACY.md'; // 'https://gitlab.com/famedly/fluffychat/-/blob/main/PRIVACY.md';

@ -275,26 +275,44 @@ class ClientChooserButton extends StatelessWidget {
color: Colors.transparent, color: Colors.transparent,
borderRadius: BorderRadius.circular(99), borderRadius: BorderRadius.circular(99),
child: child:
// #Pangea // // #Pangea
Stack( // Stack(
alignment: Alignment.bottomRight, // alignment: Alignment.bottomRight,
children: [ // children: [
Padding( // Padding(
padding: const EdgeInsets.all(4), // padding: const EdgeInsets.all(4),
child: // child:
// Pangea# // // Pangea#
Avatar( Container(
mxContent: snapshot.data?.avatarUrl, decoration: BoxDecoration(
name: snapshot.data?.displayName ?? // borderRadius: BorderRadius.circular(15),
matrix.client.userID!.localpart, // color: Theme.of(context).colorScheme.surfaceBright,
size: 50, borderRadius: BorderRadius.circular(30),
boxShadow: [
BoxShadow(
color: Theme.of(context).colorScheme.primary,
spreadRadius: 1,
blurRadius: 1,
offset: const Offset(
0,
1,
), // changes position of shadow
), ),
// #Pangea ],
), ),
const Icon(Icons.settings_outlined, size: 20), child: Avatar(
], mxContent: snapshot.data?.avatarUrl,
name: snapshot.data?.displayName ??
matrix.client.userID!.localpart,
size: 60,
),
), ),
// Pangea# // // #Pangea
// ),
// const Icon(Icons.settings_outlined, size: 20),
// ],
// ),
// // Pangea#
), ),
), ),
], ],

@ -13,7 +13,7 @@ extension ProgressIndicatorsExtension on ProgressIndicatorEnum {
IconData get icon { IconData get icon {
switch (this) { switch (this) {
case ProgressIndicatorEnum.wordsUsed: case ProgressIndicatorEnum.wordsUsed:
return Icons.text_fields_outlined; return Symbols.dictionary;
case ProgressIndicatorEnum.morphsUsed: case ProgressIndicatorEnum.morphsUsed:
return Symbols.toys_and_games; return Symbols.toys_and_games;
case ProgressIndicatorEnum.level: case ProgressIndicatorEnum.level:
@ -25,24 +25,7 @@ extension ProgressIndicatorsExtension on ProgressIndicatorEnum {
Theme.of(context).brightness == Brightness.dark; Theme.of(context).brightness == Brightness.dark;
Color color(BuildContext context) { Color color(BuildContext context) {
switch (this) { return Theme.of(context).colorScheme.primary;
case ProgressIndicatorEnum.wordsUsed:
return Theme.of(context).brightness == Brightness.dark
? const Color.fromARGB(255, 169, 183, 237)
: const Color.fromARGB(255, 38, 59, 141);
// case ProgressIndicatorEnum.errorTypes:
// return Theme.of(context).brightness == Brightness.dark
// ? const Color.fromARGB(255, 212, 144, 216)
// : const Color.fromARGB(255, 163, 39, 169);
case ProgressIndicatorEnum.level:
return Theme.of(context).brightness == Brightness.dark
? const Color.fromARGB(255, 250, 220, 129)
: const Color.fromARGB(255, 255, 208, 67);
case ProgressIndicatorEnum.morphsUsed:
return Theme.of(context).brightness == Brightness.dark
? const Color.fromARGB(255, 169, 183, 237)
: const Color.fromARGB(255, 38, 59, 141);
}
} }
String tooltip(BuildContext context) { String tooltip(BuildContext context) {

@ -1,3 +1,4 @@
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/config/themes.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -5,14 +6,16 @@ class AnimatedLevelBar extends StatefulWidget {
final double height; final double height;
final double beginWidth; final double beginWidth;
final double endWidth; final double endWidth;
final BoxDecoration? decoration; final Color primaryColor;
final Color highlightColor;
const AnimatedLevelBar({ const AnimatedLevelBar({
super.key, super.key,
required this.height, required this.height,
required this.beginWidth, required this.beginWidth,
required this.endWidth, required this.endWidth,
this.decoration, required this.primaryColor,
required this.highlightColor,
}); });
@override @override
@ -76,10 +79,40 @@ class AnimatedLevelBarState extends State<AnimatedLevelBar>
return AnimatedBuilder( return AnimatedBuilder(
animation: _animation, animation: _animation,
builder: (context, child) { builder: (context, child) {
return Container( return Stack(
height: widget.height, children: [
width: _animation.value, Container(
decoration: widget.decoration, height: widget.height,
width: _animation.value,
decoration: BoxDecoration(
color: widget.primaryColor,
borderRadius: const BorderRadius.all(
Radius.circular(AppConfig.borderRadius),
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
spreadRadius: 0,
blurRadius: 5,
offset: const Offset(5, 0),
),
],
),
),
Positioned(
top: 2,
child: Container(
height: 6,
width: _animation.value >= 8 ? _animation.value - 8 : 0,
decoration: BoxDecoration(
color: widget.highlightColor,
borderRadius: const BorderRadius.all(
Radius.circular(AppConfig.borderRadius),
),
),
),
),
],
); );
}, },
); );

@ -36,19 +36,8 @@ class LevelBarState extends State<LevelBar> {
height: widget.progressBarDetails.height, height: widget.progressBarDetails.height,
beginWidth: prevWidth, beginWidth: prevWidth,
endWidth: width, endWidth: width,
decoration: BoxDecoration( primaryColor: AppConfig.gold,
borderRadius: const BorderRadius.all( highlightColor: AppConfig.goldLight,
Radius.circular(AppConfig.borderRadius),
),
color: widget.details.fillColor,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 5,
offset: const Offset(5, 0),
),
],
),
); );
} }
} }

@ -13,13 +13,9 @@ class ProgressBarBackground extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
height: details.height + 4, height: details.height,
width: details.totalWidth + 4, width: details.totalWidth,
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(
color: details.borderColor.withOpacity(0.5),
width: 2,
),
borderRadius: const BorderRadius.all( borderRadius: const BorderRadius.all(
Radius.circular(AppConfig.borderRadius), Radius.circular(AppConfig.borderRadius),
), ),

@ -20,6 +20,6 @@ class ProgressBarDetails {
const ProgressBarDetails({ const ProgressBarDetails({
required this.totalWidth, required this.totalWidth,
required this.borderColor, required this.borderColor,
this.height = 16, this.height = 14,
}); });
} }

@ -7,11 +7,12 @@ import 'package:fluffychat/pangea/models/analytics/construct_list_model.dart';
import 'package:fluffychat/pangea/pages/settings_learning/settings_learning.dart'; import 'package:fluffychat/pangea/pages/settings_learning/settings_learning.dart';
import 'package:fluffychat/pangea/widgets/chat_list/analytics_summary/analytics_popup/analytics_popup.dart'; import 'package:fluffychat/pangea/widgets/chat_list/analytics_summary/analytics_popup/analytics_popup.dart';
import 'package:fluffychat/pangea/widgets/chat_list/analytics_summary/learning_progress_bar.dart'; import 'package:fluffychat/pangea/widgets/chat_list/analytics_summary/learning_progress_bar.dart';
import 'package:fluffychat/pangea/widgets/chat_list/analytics_summary/learning_settings_button.dart';
import 'package:fluffychat/pangea/widgets/chat_list/analytics_summary/level_badge.dart'; import 'package:fluffychat/pangea/widgets/chat_list/analytics_summary/level_badge.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/pangea/widgets/flag.dart';
import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.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
@ -76,22 +77,40 @@ class LearningProgressIndicatorsState
return const SizedBox(); return const SizedBox();
} }
final userL2 = MatrixState.pangeaController.languageController.userL2;
return Row( return Row(
children: [ children: [
const ClientChooserButton(), const ClientChooserButton(),
const SizedBox(width: 6), const SizedBox(width: 10),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text(
Matrix.of(context).client.userID ?? L10n.of(context)!.user,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
fontSize: 12,
),
),
const SizedBox(height: 6),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
LearningSettingsButton(
onTap: () => showDialog(
context: context,
builder: (c) => const SettingsLearning(),
),
l2: userL2!.getDisplayName(context) ?? userL2.langCode,
),
Row( Row(
children: ProgressIndicatorEnum.values children: ProgressIndicatorEnum.values
.where((i) => i != ProgressIndicatorEnum.level) .where((i) => i != ProgressIndicatorEnum.level)
.map( .map(
(indicator) => Padding( (indicator) => Padding(
padding: const EdgeInsets.only(right: 10), padding: const EdgeInsets.only(left: 6),
child: ProgressIndicatorBadge( child: ProgressIndicatorBadge(
points: uniqueLemmas(indicator), points: uniqueLemmas(indicator),
loading: _loading, loading: _loading,
@ -111,22 +130,11 @@ class LearningProgressIndicatorsState
) )
.toList(), .toList(),
), ),
InkWell(
onTap: () => showDialog(
context: context,
builder: (c) => const SettingsLearning(),
),
child: LanguageFlag(
language: MatrixState
.pangeaController.languageController.userL2,
size: 24,
),
),
], ],
), ),
const SizedBox(height: 6), const SizedBox(height: 6),
SizedBox( SizedBox(
height: 36, height: 22,
child: Stack( child: Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [

@ -0,0 +1,62 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
/// A badge that represents one learning progress indicator (i.e., construct uses)
class LearningSettingsButton extends StatelessWidget {
final String l2;
final VoidCallback onTap;
const LearningSettingsButton({
super.key,
required this.l2,
required this.onTap,
});
@override
Widget build(BuildContext context) {
return Tooltip(
message: L10n.of(context)!.learningSettings,
child: InkWell(
customBorder: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
onTap: onTap,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Theme.of(context).colorScheme.surfaceBright,
boxShadow: [
BoxShadow(
color: Theme.of(context).colorScheme.primary,
spreadRadius: 1,
blurRadius: 1,
offset: const Offset(1, 1), // changes position of shadow
),
],
),
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
size: 14,
Icons.language,
color: Theme.of(context).colorScheme.primary,
weight: 1000,
),
const SizedBox(width: 5),
Text(
l2,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.primary,
),
),
],
),
),
),
);
}
}

@ -1,4 +1,6 @@
import 'package:fluffychat/config/app_config.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
class LevelBadge extends StatelessWidget { class LevelBadge extends StatelessWidget {
final int level; final int level;
@ -7,39 +9,45 @@ class LevelBadge extends StatelessWidget {
super.key, super.key,
}); });
Color levelColor(int level) {
final colors = [
const Color.fromARGB(255, 33, 97, 140), // Dark blue
const Color.fromARGB(255, 186, 104, 200), // Soft purple
const Color.fromARGB(255, 123, 31, 162), // Deep purple
const Color.fromARGB(255, 0, 150, 136), // Teal
const Color.fromARGB(255, 247, 143, 143), // Light pink
const Color.fromARGB(255, 220, 20, 60), // Crimson red
];
return colors[level % colors.length];
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
width: 32,
height: 32,
decoration: BoxDecoration( decoration: BoxDecoration(
color: levelColor(level), borderRadius: BorderRadius.circular(15),
borderRadius: BorderRadius.circular(32), color: Theme.of(context).colorScheme.surfaceBright,
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
color: Colors.black.withOpacity(0.2), color: Theme.of(context).colorScheme.primary,
blurRadius: 5, spreadRadius: 1,
offset: const Offset(5, 0), blurRadius: 1,
offset: const Offset(1, 1), // changes position of shadow
), ),
], ],
), ),
child: Center( padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
child: Text( child: Row(
"$level", mainAxisSize: MainAxisSize.min,
style: const TextStyle(color: Colors.white, fontSize: 16), children: [
), CircleAvatar(
backgroundColor: AppConfig.gold,
radius: 8,
child: Icon(
size: 12,
Icons.star,
color: Theme.of(context).colorScheme.surfaceBright,
weight: 1000,
),
),
const SizedBox(width: 4),
Text(
L10n.of(context)!.levelShort(level),
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.primary,
),
),
],
), ),
); );
} }

@ -21,31 +21,52 @@ class ProgressIndicatorBadge extends StatelessWidget {
return Tooltip( return Tooltip(
message: indicator.tooltip(context), message: indicator.tooltip(context),
child: InkWell( child: InkWell(
customBorder: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
onTap: onTap, onTap: onTap,
child: Row( child: Container(
mainAxisSize: MainAxisSize.min, decoration: BoxDecoration(
children: [ borderRadius: BorderRadius.circular(15),
Icon( color: Theme.of(context).colorScheme.surfaceBright,
indicator.icon, boxShadow: [
color: indicator.color(context), BoxShadow(
), color: Theme.of(context).colorScheme.primary,
const SizedBox(width: 5), spreadRadius: 1,
!loading blurRadius: 1,
? Text( offset: const Offset(-1, 1), // changes position of shadow
points.toString(), ),
style: const TextStyle( ],
fontSize: 16, ),
fontWeight: FontWeight.bold, padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
), child: Row(
) mainAxisSize: MainAxisSize.min,
: const SizedBox( children: [
height: 8, Icon(
width: 8, size: 14,
child: CircularProgressIndicator.adaptive( indicator.icon,
strokeWidth: 2, color: indicator.color(context),
weight: 1000,
),
const SizedBox(width: 5),
!loading
? Text(
points.toString(),
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: indicator.color(context),
),
)
: const SizedBox(
height: 8,
width: 8,
child: CircularProgressIndicator.adaptive(
strokeWidth: 2,
),
), ),
), ],
], ),
), ),
), ),
); );

Loading…
Cancel
Save