diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 3f07c4cce..bcd8868b7 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -4732,7 +4732,7 @@ "activityPlannerTitle": "Activity Planner", "topicLabel": "Topic", "topicPlaceholder": "Choose a topic...", - "modeLabel": "Mode", + "modeLabel": "Activity type", "modePlaceholder": "Choose a mode...", "learningObjectiveLabel": "Learning Objective", "learningObjectivePlaceholder": "Choose a learning objective...", @@ -4873,7 +4873,7 @@ "exploreMore": "Explore more", "randomize": "Randomize", "clear": "Clear", - "makeYourOwnActivity": "Make your own activity", + "makeYourOwnActivity": "Create your own activity", "featuredActivities": "Featured", "yourBookmarks": "Bookmarked", "goToChat": "Go to chat", @@ -5031,5 +5031,6 @@ } }, "failedToFetchTranscription": "Failed to fetch transcription", - "deleteEmptySpaceDesc": "The space will be deleted for all participants. This action cannot be undone." + "deleteEmptySpaceDesc": "The space will be deleted for all participants. This action cannot be undone.", + "regenerate": "Regenerate" } diff --git a/lib/l10n/intl_es.arb b/lib/l10n/intl_es.arb index e1407a289..2dd1d6672 100644 --- a/lib/l10n/intl_es.arb +++ b/lib/l10n/intl_es.arb @@ -5362,7 +5362,6 @@ "activityPlannerTitle": "Planificador de Actividades", "topicLabel": "Tema", "topicPlaceholder": "Elige un tema...", - "modeLabel": "Modo", "modePlaceholder": "Elige un modo...", "learningObjectiveLabel": "Objetivo de Aprendizaje", "learningObjectivePlaceholder": "Elige un objetivo de aprendizaje...", @@ -5494,7 +5493,6 @@ "exploreMore": "Explorar más", "randomize": "Aleatorizar", "clear": "Limpiar", - "makeYourOwnActivity": "Crea tu propia actividad", "featuredActivities": "Destacadas", "yourBookmarks": "Marcados", "goToChat": "Ir al chat", diff --git a/lib/l10n/intl_vi.arb b/lib/l10n/intl_vi.arb index 87d240b4d..42268e099 100644 --- a/lib/l10n/intl_vi.arb +++ b/lib/l10n/intl_vi.arb @@ -3551,7 +3551,6 @@ "activityPlannerTitle": "Trình lập hoạt động", "topicLabel": "Chủ đề", "topicPlaceholder": "Chọn một chủ đề...", - "modeLabel": "Chế độ", "modePlaceholder": "Chọn một chế độ...", "learningObjectiveLabel": "Mục tiêu học tập", "learningObjectivePlaceholder": "Chọn một mục tiêu học tập...", @@ -3834,7 +3833,6 @@ "exploreMore": "Khám phá thêm", "randomize": "Ngẫu nhiên hóa", "clear": "Xóa", - "makeYourOwnActivity": "Tạo hoạt động của riêng bạn", "featuredActivities": "Nổi bật", "yourBookmarks": "Đã đánh dấu", "goToChat": "Đi đến trò chuyện", diff --git a/lib/pangea/activity_generator/activity_generator.dart b/lib/pangea/activity_generator/activity_generator.dart index 2ed3dcd9b..2f09675ce 100644 --- a/lib/pangea/activity_generator/activity_generator.dart +++ b/lib/pangea/activity_generator/activity_generator.dart @@ -10,7 +10,6 @@ import 'package:fluffychat/pangea/activity_planner/activity_mode_list_repo.dart' import 'package:fluffychat/pangea/activity_planner/activity_plan_generation_repo.dart'; import 'package:fluffychat/pangea/activity_planner/activity_plan_model.dart'; import 'package:fluffychat/pangea/activity_planner/activity_plan_request.dart'; -import 'package:fluffychat/pangea/activity_planner/activity_plan_response.dart'; import 'package:fluffychat/pangea/activity_planner/learning_objective_list_repo.dart'; import 'package:fluffychat/pangea/activity_planner/list_request_schema.dart'; import 'package:fluffychat/pangea/activity_planner/media_enum.dart'; @@ -166,11 +165,6 @@ class ActivityGeneratorState extends State { setState(() => selectedCefrLevel = value); } - void setSelectedMedia(MediaEnum? value) { - if (value == null) return; - setState(() => selectedMedia = value); - } - Future get _selectedMode async { final modes = await modeItems; return modes.firstWhereOrNull( @@ -203,30 +197,18 @@ class ActivityGeneratorState extends State { }); } - Future onEdit(int index, ActivityPlanModel updatedActivity) async { - // in this case we're editing an activity plan that was generated recently - // via the repo and should be updated in the cached response - if (activities != null) { - activities?[index] = updatedActivity; - ActivityPlanGenerationRepo.set( - planRequest, - ActivityPlanResponse(activityPlans: activities!), - ); - } - - setState(() {}); - } - - void update() => setState(() {}); - - Future generate() async { + Future generate({bool force = false}) async { setState(() { loading = true; error = null; + activities = null; }); try { - final resp = await ActivityPlanGenerationRepo.get(planRequest); + final resp = await ActivityPlanGenerationRepo.get( + planRequest, + force: force, + ); activities = resp.activityPlans; await _setModeImageURL(); } catch (e, s) { diff --git a/lib/pangea/activity_generator/activity_generator_view.dart b/lib/pangea/activity_generator/activity_generator_view.dart index 862d523ae..b3c74551e 100644 --- a/lib/pangea/activity_generator/activity_generator_view.dart +++ b/lib/pangea/activity_generator/activity_generator_view.dart @@ -61,6 +61,7 @@ class ActivityGeneratorView extends StatelessWidget { room: controller.room, builder: (c) { return ActivityPlanCard( + regenerate: () => controller.generate(force: true), controller: c, ); }, diff --git a/lib/pangea/activity_planner/activity_plan_card.dart b/lib/pangea/activity_planner/activity_plan_card.dart index 68ed306a3..ce0a9546c 100644 --- a/lib/pangea/activity_planner/activity_plan_card.dart +++ b/lib/pangea/activity_planner/activity_plan_card.dart @@ -20,10 +20,12 @@ import 'package:fluffychat/pangea/learning_settings/enums/language_level_type_en import 'package:fluffychat/widgets/future_loading_dialog.dart'; class ActivityPlanCard extends StatefulWidget { + final VoidCallback regenerate; final ActivityPlannerBuilderState controller; const ActivityPlanCard({ super.key, + required this.regenerate, required this.controller, }); @@ -121,8 +123,11 @@ class ActivityPlanCardState extends State { AnimatedSize( duration: FluffyThemes.animationDuration, child: Stack( + alignment: Alignment.bottomCenter, children: [ Container( + width: 200.0, + padding: const EdgeInsets.all(16.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(12.0), ), @@ -131,6 +136,7 @@ class ActivityPlanCardState extends State { child: widget.controller.imageURL != null || widget.controller.avatar != null ? ClipRRect( + borderRadius: BorderRadius.circular(20.0), child: widget.controller.avatar == null ? CachedNetworkImage( fit: BoxFit.cover, @@ -156,14 +162,17 @@ class ActivityPlanCardState extends State { ), ), if (widget.controller.isEditing) - Positioned( - top: 10.0, - right: 10.0, - child: IconButton( - icon: const Icon(Icons.upload_outlined), - onPressed: widget.controller.selectAvatar, - style: IconButton.styleFrom( - backgroundColor: Colors.black, + InkWell( + borderRadius: BorderRadius.circular(90), + onTap: widget.controller.selectAvatar, + child: CircleAvatar( + backgroundColor: + Theme.of(context).colorScheme.secondary, + radius: 16.0, + child: Icon( + Icons.add_a_photo_outlined, + size: 16.0, + color: Theme.of(context).colorScheme.onSecondary, ), ), ), @@ -368,47 +377,108 @@ class ActivityPlanCardState extends State { ), ], const SizedBox(height: itemPadding), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Tooltip( - message: !widget.controller.isEditing - ? l10n.edit - : l10n.saveChanges, - child: IconButton( - icon: Icon( - !widget.controller.isEditing - ? Icons.edit - : Icons.save, + widget.controller.isEditing + ? Row( + spacing: 12.0, + children: [ + Expanded( + child: ElevatedButton( + onPressed: widget.controller.saveEdits, + child: Row( + children: [ + const Icon(Icons.save), + Expanded( + child: Text( + L10n.of(context).save, + textAlign: TextAlign.center, + ), + ), + ], + ), ), - onPressed: () => !widget.controller.isEditing - ? setState(() { - widget.controller.isEditing = true; - }) - : widget.controller.saveEdits(), - isSelected: widget.controller.isEditing, ), - ), - if (widget.controller.isEditing) - Tooltip( - message: l10n.cancel, - child: IconButton( - icon: const Icon(Icons.cancel), + Expanded( + child: ElevatedButton( onPressed: widget.controller.clearEdits, + child: Row( + children: [ + const Icon(Icons.cancel), + Expanded( + child: Text( + L10n.of(context).cancel, + textAlign: TextAlign.center, + ), + ), + ], + ), ), ), - ], - ), - ElevatedButton.icon( - onPressed: - !widget.controller.isEditing ? _onLaunch : null, - icon: const Icon(Icons.send), - label: Text(l10n.launchActivityButton), - ), - ], - ), + ], + ) + : Column( + spacing: 12.0, + children: [ + Row( + spacing: 12.0, + children: [ + Expanded( + child: ElevatedButton( + child: Row( + children: [ + const Icon(Icons.edit), + Expanded( + child: Text( + L10n.of(context).edit, + textAlign: TextAlign.center, + ), + ), + ], + ), + onPressed: () => + widget.controller.setEditing(true), + ), + ), + Expanded( + child: ElevatedButton( + onPressed: widget.regenerate, + child: Row( + children: [ + const Icon(Icons.lightbulb_outline), + Expanded( + child: Text( + L10n.of(context).regenerate, + textAlign: TextAlign.center, + ), + ), + ], + ), + ), + ), + ], + ), + Row( + children: [ + Expanded( + child: ElevatedButton( + onPressed: _onLaunch, + child: Row( + children: [ + const Icon(Icons.send), + Expanded( + child: Text( + L10n.of(context) + .launchActivityButton, + textAlign: TextAlign.center, + ), + ), + ], + ), + ), + ), + ], + ), + ], + ), ], ), ), diff --git a/lib/pangea/activity_planner/activity_plan_generation_repo.dart b/lib/pangea/activity_planner/activity_plan_generation_repo.dart index 70e079e85..261b41a20 100644 --- a/lib/pangea/activity_planner/activity_plan_generation_repo.dart +++ b/lib/pangea/activity_planner/activity_plan_generation_repo.dart @@ -18,9 +18,12 @@ class ActivityPlanGenerationRepo { _activityPlanStorage.write(request.storageKey, response.toJson()); } - static Future get(ActivityPlanRequest request) async { + static Future get( + ActivityPlanRequest request, { + bool force = false, + }) async { final cachedJson = _activityPlanStorage.read(request.storageKey); - if (cachedJson != null) { + if (cachedJson != null && !force) { final cached = ActivityPlanResponse.fromJson(cachedJson); return cached; diff --git a/lib/pangea/activity_planner/activity_planner_builder.dart b/lib/pangea/activity_planner/activity_planner_builder.dart index 42e84bce2..d2ec4bdf2 100644 --- a/lib/pangea/activity_planner/activity_planner_builder.dart +++ b/lib/pangea/activity_planner/activity_planner_builder.dart @@ -7,6 +7,7 @@ import 'package:http/http.dart'; import 'package:matrix/matrix.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/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/pangea/learning_settings/enums/language_level_type_enum.dart'; @@ -21,18 +22,12 @@ class ActivityPlannerBuilder extends StatefulWidget { final Widget Function(ActivityPlannerBuilderState) builder; - final Future Function( - String, - ActivityPlanModel, - )? onEdit; - const ActivityPlannerBuilder({ super.key, required this.initialActivity, this.initialFilename, this.room, required this.builder, - this.onEdit, }); @override @@ -206,12 +201,10 @@ class ActivityPlannerBuilderState extends State { if (!formKey.currentState!.validate()) return; await updateImageURL(); setEditing(false); - if (widget.onEdit != null) { - await widget.onEdit!( - widget.initialActivity.bookmarkId, - updatedActivity, - ); - } + + await BookmarkedActivitiesRepo.remove(widget.initialActivity.bookmarkId); + await BookmarkedActivitiesRepo.save(updatedActivity); + if (mounted) setState(() {}); } Future clearEdits() async { diff --git a/lib/pangea/activity_planner/bookmarked_activity_list.dart b/lib/pangea/activity_planner/bookmarked_activity_list.dart index e11bf9f0b..241a162ef 100644 --- a/lib/pangea/activity_planner/bookmarked_activity_list.dart +++ b/lib/pangea/activity_planner/bookmarked_activity_list.dart @@ -36,15 +36,6 @@ class BookmarkedActivitiesListState extends State { double get cardHeight => _isColumnMode ? 325.0 : 250.0; double get cardWidth => _isColumnMode ? 225.0 : 150.0; - Future _onEdit( - String activityId, - ActivityPlanModel activity, - ) async { - await BookmarkedActivitiesRepo.remove(activityId); - await BookmarkedActivitiesRepo.save(activity); - if (mounted) setState(() {}); - } - @override Widget build(BuildContext context) { final l10n = L10n.of(context); @@ -77,7 +68,6 @@ class BookmarkedActivitiesListState extends State { builder: (context) { return ActivityPlannerBuilder( initialActivity: activity, - onEdit: _onEdit, room: widget.room, builder: (controller) { return ActivitySuggestionDialog(