Merge pull request #895 from pangeachat/867-learning-analytics-main-menu-redesign
updates to main menu design
This commit is contained in:
commit
d61d746cee
9 changed files with 266 additions and 149 deletions
|
|
@ -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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
82
lib/pangea/widgets/chat_list/pangea_chat_list_header.dart
Normal file
82
lib/pangea/widgets/chat_list/pangea_chat_list_header.dart
Normal file
|
|
@ -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…
Add table
Reference in a new issue