chore: updates to activity suggestion card design (#2293)

This commit is contained in:
ggurdin 2025-03-31 16:28:25 -04:00 committed by GitHub
parent 9142d1f31d
commit c60b16dfe2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 194 additions and 291 deletions

View file

@ -4846,5 +4846,7 @@
"selectActivity": "Select activity",
"newChatActivityDesc": "Make every group chat an adventure with Activity Planner! Set captivating topics and objectives for the group, and bring conversations to life with stunning images. Spark imaginative discussions and keep the fun flowing effortlessly!",
"exploreMore": "Explore more",
"wordFocusListeningMultipleChoice": "Which audio matches the word?"
"wordFocusListeningMultipleChoice": "Which audio matches the word?",
"createActivity": "Create activity",
"startChat": "Start a chat"
}

View file

@ -35,7 +35,7 @@ class BookmarkedActivitiesListState extends State<BookmarkedActivitiesList> {
bool get _isColumnMode => FluffyThemes.isColumnMode(context);
final double cardHeight = 250.0;
double get cardHeight => _isColumnMode ? 315.0 : 240.0;
double get cardPadding => _isColumnMode ? 8.0 : 0.0;
double get cardWidth => _isColumnMode ? 225.0 : 150.0;

View file

@ -3,11 +3,9 @@ import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/pangea/activity_planner/activity_plan_model.dart';
import 'package:fluffychat/pangea/activity_planner/bookmarked_activities_repo.dart';
import 'package:fluffychat/pangea/activity_suggestions/activity_suggestion_card_row.dart';
import 'package:fluffychat/pangea/common/widgets/pressable_button.dart';
import 'package:fluffychat/widgets/mxc_image.dart';
@ -75,11 +73,12 @@ class ActivitySuggestionCard extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
height: 100,
width: width,
height: width - 16.0,
width: width - 16.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.0),
),
margin: const EdgeInsets.only(top: 8.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(24.0),
child: image != null
@ -88,8 +87,8 @@ class ActivitySuggestionCard extends StatelessWidget {
? activity.imageURL!.startsWith("mxc")
? MxcImage(
uri: Uri.parse(activity.imageURL!),
width: width,
height: 100,
width: width - 16.0,
height: width - 16.0,
cacheKey: activity.bookmarkId,
)
: CachedNetworkImage(
@ -109,68 +108,73 @@ class ActivitySuggestionCard extends StatelessWidget {
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(
top: 12.0,
left: 12.0,
right: 12.0,
bottom: 12.0,
),
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
spacing: 8.0,
children: [
ActivitySuggestionCardRow(
icon: Icons.event_note_outlined,
child: Text(
activity.title,
style: const TextStyle(
fontWeight: FontWeight.bold,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 54.0),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Align(
alignment: Alignment.topLeft,
child: Wrap(
spacing: 4.0,
runSpacing: 4.0,
children: activity.vocab
.map(
(vocab) => Container(
padding: const EdgeInsets.symmetric(
vertical: 4.0,
horizontal: 8.0,
),
decoration: BoxDecoration(
color: theme.colorScheme.primary
.withAlpha(50),
borderRadius:
BorderRadius.circular(24.0),
),
child: Text(
vocab.lemma,
style: theme.textTheme.bodySmall,
),
),
)
.toList(),
Row(
children: [
Flexible(
child: Text(
activity.title,
style: const TextStyle(
fontWeight: FontWeight.bold,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
),
],
),
ActivitySuggestionCardRow(
icon: Icons.group_outlined,
child: Text(
L10n.of(context).countParticipants(
activity.req.numberOfParticipants,
Row(
mainAxisSize: MainAxisSize.min,
spacing: 8.0,
children: [
Container(
decoration: BoxDecoration(
color: theme.colorScheme.primaryContainer,
borderRadius: BorderRadius.circular(24.0),
),
padding: const EdgeInsets.symmetric(
vertical: 4.0,
horizontal: 8.0,
),
child: Row(
mainAxisSize: MainAxisSize.min,
spacing: 8.0,
children: [
const Icon(
Icons.group_outlined,
size: 16.0,
),
Text(
"${activity.req.numberOfParticipants}",
style: theme.textTheme.bodySmall,
),
],
),
),
style: theme.textTheme.bodySmall,
),
if (activity.req.mode.isNotEmpty)
Flexible(
child: Container(
decoration: BoxDecoration(
color: theme.colorScheme.primaryContainer,
borderRadius: BorderRadius.circular(24.0),
),
padding: const EdgeInsets.symmetric(
vertical: 4.0,
horizontal: 8.0,
),
child: Text(
activity.req.mode,
style: theme.textTheme.bodySmall,
overflow: TextOverflow.ellipsis,
),
),
),
],
),
],
),
@ -200,7 +204,9 @@ class ActivitySuggestionCard extends StatelessWidget {
onChange();
}
: null,
iconSize: 24.0,
style: IconButton.styleFrom(
backgroundColor: Colors.black.withAlpha(200),
),
),
),
],

View file

@ -48,8 +48,8 @@ class ActivitySuggestionCarouselState
bool _loading = true;
String? _error;
double get _cardWidth => _isColumnMode ? 250.0 : 200.0;
final double _cardHeight = 275.0;
double get _cardWidth => _isColumnMode ? 250.0 : 175.0;
double get _cardHeight => _isColumnMode ? 350.0 : 265.0;
ActivityPlanModel? _currentActivity;
final List<ActivityPlanModel> _activityItems = [];
@ -161,24 +161,33 @@ class ActivitySuggestionCarouselState
border: Border.all(color: theme.dividerColor),
borderRadius: BorderRadius.circular(24.0),
),
padding: const EdgeInsets.all(16.0),
padding: const EdgeInsets.symmetric(
vertical: 16.0,
horizontal: 4.0,
),
child: Column(
spacing: 16.0,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
L10n.of(context).newChatActivityTitle,
style: theme.textTheme.titleLarge,
),
IconButton(
icon: const Icon(Icons.close),
onPressed: widget.enabled ? _close : null,
),
],
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
L10n.of(context).newChatActivityTitle,
style: theme.textTheme.titleLarge,
),
IconButton(
icon: const Icon(Icons.close),
onPressed: widget.enabled ? _close : null,
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Text(L10n.of(context).newChatActivityDesc),
),
Text(L10n.of(context).newChatActivityDesc),
Row(
spacing: _isColumnMode ? 16.0 : 4.0,
mainAxisAlignment: MainAxisAlignment.center,

View file

@ -13,8 +13,6 @@ import 'package:fluffychat/pangea/activity_planner/media_enum.dart';
import 'package:fluffychat/pangea/activity_suggestions/activity_plan_search_repo.dart';
import 'package:fluffychat/pangea/activity_suggestions/activity_suggestion_card.dart';
import 'package:fluffychat/pangea/activity_suggestions/activity_suggestion_dialog.dart';
import 'package:fluffychat/pangea/activity_suggestions/create_chat_card.dart';
import 'package:fluffychat/pangea/activity_suggestions/make_activity_card.dart';
import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart';
import 'package:fluffychat/pangea/learning_settings/enums/language_level_type_enum.dart';
import 'package:fluffychat/widgets/matrix.dart';
@ -54,7 +52,7 @@ class ActivitySuggestionsAreaState extends State<ActivitySuggestionsArea> {
final List<ActivityPlanModel> _activityItems = [];
final ScrollController _scrollController = ScrollController();
final double cardHeight = 250.0;
double get cardHeight => _isColumnMode ? 315.0 : 240.0;
double get cardPadding => _isColumnMode ? 8.0 : 0.0;
double get cardWidth => _isColumnMode ? 225.0 : 150.0;
@ -106,29 +104,6 @@ class ActivitySuggestionsAreaState extends State<ActivitySuggestionsArea> {
.cast<Widget>()
.toList();
if (widget.showMakeActivityCard) {
cards.insert(
0,
MakeActivityCard(
width: cardWidth,
height: cardHeight,
padding: cardPadding,
roomID: widget.room?.id,
),
);
}
if (widget.showCreateChatCard) {
cards.insert(
0,
CreateChatCard(
width: cardWidth,
height: cardHeight,
padding: cardPadding,
),
);
}
final scrollDirection = widget.scrollDirection ??
(_isColumnMode ? Axis.horizontal : Axis.vertical);

View file

@ -1,73 +0,0 @@
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/pangea/activity_suggestions/activity_suggestions_constants.dart';
import 'package:fluffychat/pangea/common/widgets/customized_svg.dart';
import 'package:fluffychat/pangea/common/widgets/pressable_button.dart';
class CreateChatCard extends StatelessWidget {
final double width;
final double height;
final double padding;
const CreateChatCard({
required this.width,
required this.height,
required this.padding,
super.key,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Padding(
padding: EdgeInsets.all(padding),
child: PressableButton(
onPressed: () => context.go('/rooms/newgroup'),
borderRadius: BorderRadius.circular(24.0),
color: theme.brightness == Brightness.dark
? theme.colorScheme.primary
: theme.colorScheme.surfaceContainerHighest,
colorFactor: theme.brightness == Brightness.dark ? 0.6 : 0.2,
child: Container(
decoration: BoxDecoration(
color: theme.colorScheme.surfaceContainer,
borderRadius: BorderRadius.circular(24.0),
),
height: height,
width: width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: CustomizedSvg(
svgUrl:
"${AppConfig.assetsBaseURL}/${ActivitySuggestionsConstants.plusIconPath}",
colorReplacements: {
"#CDBEF9":
colorToHex(Theme.of(context).colorScheme.secondary),
},
height: 80,
width: 80,
),
),
const SizedBox(height: 16.0),
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
L10n.of(context).createOwnChat,
style: theme.textTheme.bodyLarge
?.copyWith(color: theme.colorScheme.secondary),
textAlign: TextAlign.center,
),
),
],
),
),
),
);
}
}

View file

@ -1,79 +0,0 @@
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/pangea/activity_suggestions/activity_suggestions_constants.dart';
import 'package:fluffychat/pangea/common/widgets/customized_svg.dart';
import 'package:fluffychat/pangea/common/widgets/pressable_button.dart';
class MakeActivityCard extends StatelessWidget {
final double width;
final double height;
final double padding;
final String? roomID;
const MakeActivityCard({
required this.width,
required this.height,
required this.padding,
this.roomID,
super.key,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Padding(
padding: EdgeInsets.all(padding),
child: PressableButton(
onPressed: () {
roomID == null
? context.go('/rooms/planner')
: context.go('/rooms/${roomID!}/planner/generator');
},
borderRadius: BorderRadius.circular(24.0),
color: theme.brightness == Brightness.dark
? theme.colorScheme.primary
: theme.colorScheme.surfaceContainerHighest,
colorFactor: theme.brightness == Brightness.dark ? 0.6 : 0.2,
child: Container(
decoration: BoxDecoration(
color: theme.colorScheme.surfaceContainer,
borderRadius: BorderRadius.circular(24.0),
),
height: height,
width: width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: CustomizedSvg(
svgUrl:
"${AppConfig.assetsBaseURL}/${ActivitySuggestionsConstants.crayonIconPath}",
colorReplacements: {
"#CDBEF9":
colorToHex(Theme.of(context).colorScheme.secondary),
},
height: 80,
width: 80,
),
),
const SizedBox(height: 16.0),
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
L10n.of(context).makeYourOwnActivity,
style: theme.textTheme.bodyLarge
?.copyWith(color: theme.colorScheme.secondary),
textAlign: TextAlign.center,
),
),
],
),
),
),
);
}
}

View file

@ -1,12 +1,14 @@
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/pangea/activity_suggestions/activity_suggestions_area.dart';
import 'package:fluffychat/pangea/activity_suggestions/activity_suggestions_constants.dart';
import 'package:fluffychat/pangea/analytics_summary/learning_progress_indicators.dart';
import 'package:fluffychat/pangea/common/widgets/pangea_logo_svg.dart';
import 'package:fluffychat/pangea/common/widgets/customized_svg.dart';
class SuggestionsPage extends StatelessWidget {
const SuggestionsPage({super.key});
@ -33,47 +35,108 @@ class SuggestionsPage extends StatelessWidget {
),
Padding(
padding: EdgeInsets.only(
left: isColumnMode ? 12.0 : 4.0,
right: isColumnMode ? 12.0 : 4.0,
left: isColumnMode ? 0.0 : 4.0,
right: isColumnMode ? 0.0 : 4.0,
top: 16.0,
bottom: 16.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
L10n.of(context).learnByTexting,
style: isColumnMode
? theme.textTheme.titleLarge
?.copyWith(fontWeight: FontWeight.bold)
: theme.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
Flexible(
child: Text(
L10n.of(context).startChat,
style: isColumnMode
? theme.textTheme.titleLarge
?.copyWith(fontWeight: FontWeight.bold)
: theme.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
overflow: TextOverflow.ellipsis,
),
),
Container(
decoration: BoxDecoration(
color: theme.colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.circular(36.0),
),
padding: const EdgeInsets.symmetric(
vertical: 6.0,
horizontal: 10.0,
),
child: Row(
spacing: 8.0,
children: [
PangeaLogoSvg(
width: 16.0,
forceColor: theme.colorScheme.primary,
),
Text(
AppConfig.applicationName,
style: theme.textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.bold,
Row(
spacing: 8.0,
children: [
InkWell(
customBorder: const CircleBorder(),
onTap: () => context.go('/rooms/newgroup'),
child: Container(
decoration: BoxDecoration(
color: theme.colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.circular(36.0),
),
padding: const EdgeInsets.symmetric(
vertical: 6.0,
horizontal: 10.0,
),
child: Row(
spacing: 8.0,
mainAxisSize: MainAxisSize.min,
children: [
CustomizedSvg(
svgUrl:
"${AppConfig.assetsBaseURL}/${ActivitySuggestionsConstants.plusIconPath}",
colorReplacements: {
"#CDBEF9": colorToHex(
Theme.of(context).colorScheme.secondary,
),
},
height: 16.0,
width: 16.0,
),
Text(
isColumnMode
? L10n.of(context).createOwnChat
: L10n.of(context).chat,
style: theme.textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.bold,
),
),
],
),
),
],
),
),
InkWell(
customBorder: const CircleBorder(),
onTap: () => context.go('/rooms/planner'),
child: Container(
decoration: BoxDecoration(
color: theme.colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.circular(36.0),
),
padding: const EdgeInsets.symmetric(
vertical: 6.0,
horizontal: 10.0,
),
child: Row(
spacing: 8.0,
mainAxisSize: MainAxisSize.min,
children: [
CustomizedSvg(
svgUrl:
"${AppConfig.assetsBaseURL}/${ActivitySuggestionsConstants.crayonIconPath}",
colorReplacements: {
"#CDBEF9": colorToHex(
Theme.of(context).colorScheme.secondary,
),
},
height: 16.0,
width: 16.0,
),
Text(
isColumnMode
? L10n.of(context).makeYourOwnActivity
: L10n.of(context).createActivity,
style: theme.textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.bold,
),
),
],
),
),
),
],
),
],
),