Merge pull request #5277 from pangeachat/5260-message-options-reorganization

chore: move regeneration button down to toolbar
This commit is contained in:
ggurdin 2026-01-20 14:52:08 -05:00 committed by GitHub
commit 573ee4dddd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 39 additions and 87 deletions

View file

@ -2418,6 +2418,8 @@ class ChatController extends State<ChatPageWithRoom>
);
if (reason == null) return;
clearSelectedEvents();
await showFutureLoadingDialog(
context: context,
future: () => room.sendEvent(

View file

@ -16,7 +16,6 @@ import 'package:fluffychat/pangea/activity_sessions/activity_summary_widget.dart
import 'package:fluffychat/pangea/bot/utils/bot_name.dart';
import 'package:fluffychat/pangea/bot/widgets/bot_settings_language_icon.dart';
import 'package:fluffychat/pangea/chat/extensions/custom_room_display_extension.dart';
import 'package:fluffychat/pangea/chat/widgets/request_regeneration_button.dart';
import 'package:fluffychat/pangea/common/widgets/pressable_button.dart';
import 'package:fluffychat/pangea/common/widgets/shimmer_background.dart';
import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart';
@ -822,20 +821,7 @@ class Message extends StatelessWidget {
),
],
),
)
// #Pangea
else if (canRefresh)
RequestRegenerationButton(
textColor:
textColor,
onPressed: () =>
controller
.requestRegeneration(
event
.eventId,
),
),
// Pangea#
],
),
),

View file

@ -1,59 +0,0 @@
import 'package:flutter/material.dart';
import 'package:fluffychat/l10n/l10n.dart';
class RequestRegenerationButton extends StatelessWidget {
final Color textColor;
final VoidCallback onPressed;
const RequestRegenerationButton({
super.key,
required this.textColor,
required this.onPressed,
});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
bottom: 8.0,
left: 16.0,
right: 16.0,
),
child: TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
minimumSize: const Size(
0,
0,
),
),
onPressed: onPressed,
child: Row(
mainAxisSize: MainAxisSize.min,
spacing: 4.0,
children: [
Icon(
Icons.refresh,
color: textColor.withAlpha(
164,
),
size: 14,
),
Text(
L10n.of(
context,
).requestRegeneration,
style: TextStyle(
color: textColor.withAlpha(
164,
),
fontSize: 11,
),
),
],
),
),
);
}
}

View file

@ -10,7 +10,6 @@ import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/chat.dart';
import 'package:fluffychat/pages/chat/events/message_content.dart';
import 'package:fluffychat/pages/chat/events/reply_content.dart';
import 'package:fluffychat/pangea/chat/widgets/request_regeneration_button.dart';
import 'package:fluffychat/pangea/common/utils/async_state.dart';
import 'package:fluffychat/pangea/common/widgets/error_indicator.dart';
import 'package:fluffychat/pangea/events/extensions/pangea_event_extension.dart';
@ -258,11 +257,6 @@ class OverlayMessage extends StatelessWidget {
),
],
),
)
else if (canRefresh)
RequestRegenerationButton(
textColor: textColor,
onPressed: () => controller.requestRegeneration(event.eventId),
),
],
),

View file

@ -29,7 +29,8 @@ enum SelectMode {
translate(Icons.translate),
practice(Symbols.fitness_center),
emoji(Icons.add_reaction_outlined),
speechTranslation(Icons.translate);
speechTranslation(Icons.translate),
requestRegenerate(Icons.replay);
final IconData icon;
const SelectMode(this.icon);
@ -46,6 +47,8 @@ enum SelectMode {
return l10n.practice;
case SelectMode.emoji:
return l10n.emojiView;
case SelectMode.requestRegenerate:
return l10n.requestRegeneration;
}
}
}
@ -180,6 +183,9 @@ class SelectModeButtonsState extends State<SelectModeButtons> {
SelectModeController get controller =>
widget.overlayController.selectModeController;
bool get _canRefresh =>
messageEvent.eventId == widget.controller.refreshEventID;
Future<void> updateMode(SelectMode? mode) async {
if (mode == null) {
matrix?.audioPlayer?.stop();
@ -214,6 +220,16 @@ class SelectModeButtonsState extends State<SelectModeButtons> {
if (updatedMode == SelectMode.speechTranslation) {
await controller.fetchSpeechTranslation();
}
if (updatedMode == SelectMode.requestRegenerate) {
await widget.controller.requestRegeneration(
messageEvent.eventId,
);
if (mounted) {
controller.setSelectMode(null);
}
}
}
Future<void> modeDisabled() async {
@ -370,7 +386,7 @@ class SelectModeButtonsState extends State<SelectModeButtons> {
Widget build(BuildContext context) {
final theme = Theme.of(context);
final modes = controller.readingAssistanceModes;
final allModes = controller.allModes;
final allModes = controller.allModes(enableRefresh: _canRefresh);
return Material(
type: MaterialType.transparency,
child: SizedBox(
@ -380,7 +396,7 @@ class SelectModeButtonsState extends State<SelectModeButtons> {
children: List.generate(allModes.length + 1, (index) {
if (index < allModes.length) {
final mode = allModes[index];
final enabled = modes.contains(mode);
final enabled = modes(enableRefresh: _canRefresh).contains(mode);
return Container(
width: 45.0,
alignment: Alignment.center,

View file

@ -130,7 +130,7 @@ class SelectModeController with LemmaEmojiSetter {
(PangeaAudioFile, File?)? get audioFile => _audioLoader.value;
List<SelectMode> get allModes {
List<SelectMode> allModes({bool enableRefresh = false}) {
final validTypes = {MessageTypes.Text, MessageTypes.Audio};
if (!messageEvent.event.status.isSent ||
messageEvent.event.type != EventTypes.Message ||
@ -138,12 +138,18 @@ class SelectModeController with LemmaEmojiSetter {
return [];
}
return messageEvent.event.messageType == MessageTypes.Text
final types = messageEvent.event.messageType == MessageTypes.Text
? _textModes
: _audioModes;
if (enableRefresh) {
return [...types, SelectMode.requestRegenerate];
}
return types;
}
List<SelectMode> get readingAssistanceModes {
List<SelectMode> readingAssistanceModes({bool enableRefresh = false}) {
final validTypes = {MessageTypes.Text, MessageTypes.Audio};
if (!messageEvent.event.status.isSent ||
messageEvent.event.type != EventTypes.Message ||
@ -151,6 +157,7 @@ class SelectModeController with LemmaEmojiSetter {
return [];
}
List<SelectMode> modes = [];
if (messageEvent.event.messageType == MessageTypes.Text) {
final lang = messageEvent.messageDisplayLangCode.split("-").first;
@ -160,14 +167,20 @@ class SelectModeController with LemmaEmojiSetter {
final matchesL1 = lang ==
MatrixState.pangeaController.userController.userL1!.langCodeShort;
return matchesL2
modes = matchesL2
? _textModes
: matchesL1
? []
: [SelectMode.translate];
} else {
modes = _audioModes;
}
return _audioModes;
if (enableRefresh) {
modes = [...modes, SelectMode.requestRegenerate];
}
return modes;
}
bool get isLoading => currentModeStateNotifier?.value is AsyncLoading;