feat: different styling for activity plan messages (#1558)

* feat: different styling for activity plan messages
pull/1593/head
ggurdin 10 months ago committed by GitHub
parent 62d5197411
commit 1d8e68a147
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -10,6 +10,8 @@ import 'package:fluffychat/pages/chat/events/message.dart';
import 'package:fluffychat/pages/chat/seen_by_row.dart';
import 'package:fluffychat/pages/chat/typing_indicators.dart';
import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart';
import 'package:fluffychat/pangea/activity_planner/activity_plan_message.dart';
import 'package:fluffychat/pangea/events/extensions/pangea_event_extension.dart';
import 'package:fluffychat/pangea/instructions/instructions_enum.dart';
import 'package:fluffychat/pangea/instructions/instructions_show_popup.dart';
import 'package:fluffychat/utils/account_config.dart';
@ -168,49 +170,64 @@ class ChatEventList extends StatelessWidget {
key: ValueKey(event.eventId),
index: i,
controller: controller.scrollController,
child: Message(
event,
animateIn: animateIn,
resetAnimateIn: () {
controller.animateInEventIndex = null;
},
onSwipe: () => controller.replyAction(replyTo: event),
// #Pangea
onInfoTab: (_) => {},
// onInfoTab: controller.showEventInfo,
// Pangea#
onAvatarTab: (Event event) => showAdaptiveBottomSheet(
context: context,
builder: (c) => UserBottomSheet(
user: event.senderFromMemoryOrFallback,
outerContext: context,
onMention: () => controller.sendController.text +=
'${event.senderFromMemoryOrFallback.mention} ',
),
),
highlightMarker:
controller.scrollToEventIdMarker == event.eventId,
// #Pangea
// onSelect: controller.onSelectMessage,
onSelect: (_) {},
// Pangea#
scrollToEventId: (String eventId) =>
controller.scrollToEventId(eventId),
longPressSelect: controller.selectedEvents.isNotEmpty,
// #Pangea
immersionMode: controller.choreographer.immersionMode,
controller: controller,
isButton: event.eventId == controller.buttonEventID,
// Pangea#
selected: controller.selectedEvents
.any((e) => e.eventId == event.eventId),
timeline: timeline,
displayReadMarker:
i > 0 && controller.readMarkerEventId == event.eventId,
nextEvent: i + 1 < events.length ? events[i + 1] : null,
previousEvent: i > 0 ? events[i - 1] : null,
wallpaperMode: hasWallpaper,
),
child:
// #Pangea
event.isActivityMessage
? ActivityPlanMessage(
event,
controller: controller,
timeline: timeline,
animateIn: animateIn,
resetAnimateIn: () {
controller.animateInEventIndex = null;
},
)
:
// Pangea#
Message(
event,
animateIn: animateIn,
resetAnimateIn: () {
controller.animateInEventIndex = null;
},
onSwipe: () => controller.replyAction(replyTo: event),
// #Pangea
onInfoTab: (_) => {},
// onInfoTab: controller.showEventInfo,
// Pangea#
onAvatarTab: (Event event) => showAdaptiveBottomSheet(
context: context,
builder: (c) => UserBottomSheet(
user: event.senderFromMemoryOrFallback,
outerContext: context,
onMention: () => controller.sendController.text +=
'${event.senderFromMemoryOrFallback.mention} ',
),
),
highlightMarker:
controller.scrollToEventIdMarker == event.eventId,
// #Pangea
// onSelect: controller.onSelectMessage,
onSelect: (_) {},
// Pangea#
scrollToEventId: (String eventId) =>
controller.scrollToEventId(eventId),
longPressSelect: controller.selectedEvents.isNotEmpty,
// #Pangea
immersionMode: controller.choreographer.immersionMode,
controller: controller,
isButton: event.eventId == controller.buttonEventID,
// Pangea#
selected: controller.selectedEvents
.any((e) => e.eventId == event.eventId),
timeline: timeline,
displayReadMarker: i > 0 &&
controller.readMarkerEventId == event.eventId,
nextEvent:
i + 1 < events.length ? events[i + 1] : null,
previousEvent: i > 0 ? events[i - 1] : null,
wallpaperMode: hasWallpaper,
),
);
},
childCount: events.length + 2,

@ -0,0 +1,241 @@
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/pages/chat/chat.dart';
import 'package:fluffychat/pages/chat/events/message_content.dart';
import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart';
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:swipe_to_action/swipe_to_action.dart';
import '../../../config/app_config.dart';
class ActivityPlanMessage extends StatelessWidget {
final Event event;
final Timeline timeline;
final bool animateIn;
final void Function()? resetAnimateIn;
final ChatController controller;
const ActivityPlanMessage(
this.event, {
required this.timeline,
this.animateIn = false,
this.resetAnimateIn,
required this.controller,
super.key,
});
@override
Widget build(BuildContext context) {
PangeaMessageEvent? pangeaMessageEvent;
if (event.type == EventTypes.Message) {
pangeaMessageEvent = PangeaMessageEvent(
event: event,
timeline: timeline,
ownMessage: event.senderId == Matrix.of(context).client.userID,
);
}
WidgetsBinding.instance.addPostFrameCallback((_) {
if (controller.pangeaEditingEvent?.eventId == event.eventId) {
pangeaMessageEvent?.updateLatestEdit();
controller.clearEditingEvent();
}
});
final theme = Theme.of(context);
final color = Color.alphaBlend(
Colors.white.withAlpha(180),
ThemeData.dark().colorScheme.primary,
);
final textColor = ThemeData.dark().colorScheme.onPrimary;
final displayEvent = event.getDisplayEvent(timeline);
const roundedCorner = Radius.circular(AppConfig.borderRadius);
const borderRadius = BorderRadius.all(roundedCorner);
final resetAnimateIn = this.resetAnimateIn;
var animateIn = this.animateIn;
final row = StatefulBuilder(
builder: (context, setState) {
if (animateIn && resetAnimateIn != null) {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
animateIn = false;
if (context.mounted) {
setState(resetAnimateIn);
}
});
}
return AnimatedSize(
duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve,
clipBehavior: Clip.none,
alignment: Alignment.bottomLeft,
child: animateIn
? const SizedBox(height: 0, width: double.infinity)
: Container(
alignment: Alignment.center,
child: AnimatedOpacity(
opacity: animateIn
? 0
: event.messageType == MessageTypes.BadEncrypted ||
event.status.isSending
? 0.5
: 1,
duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve,
child: Container(
decoration: BoxDecoration(
color: color,
borderRadius: borderRadius,
),
clipBehavior: Clip.antiAlias,
child: CompositedTransformTarget(
link: MatrixState.pAnyState
.layerLinkAndKey(
event.eventId,
)
.link,
child: Container(
key: MatrixState.pAnyState
.layerLinkAndKey(
event.eventId,
)
.key,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
AppConfig.borderRadius,
),
),
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
constraints: const BoxConstraints(
maxWidth: FluffyThemes.columnWidth * 1.5,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
MessageContent(
displayEvent,
textColor: textColor,
borderRadius: borderRadius,
pangeaMessageEvent: pangeaMessageEvent,
controller: controller,
immersionMode: false,
),
if (event.hasAggregatedEvents(
timeline,
RelationshipTypes.edit,
))
Padding(
padding: const EdgeInsets.only(
top: 4.0,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (event.hasAggregatedEvents(
timeline,
RelationshipTypes.edit,
)) ...[
Icon(
Icons.edit_outlined,
color: textColor.withAlpha(164),
size: 14,
),
Text(
' - ${displayEvent.originServerTs.localizedTimeShort(context)}',
style: TextStyle(
color: textColor.withAlpha(
164,
),
fontSize: 12,
),
),
],
],
),
),
],
),
),
),
),
),
),
);
},
);
Widget container;
container = Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Center(
child: Padding(
padding: const EdgeInsets.only(top: 4.0),
child: Material(
borderRadius: BorderRadius.circular(AppConfig.borderRadius * 2),
color: theme.colorScheme.surface.withAlpha(128),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8.0,
vertical: 2.0,
),
child: Text(
event.originServerTs.localizedTime(context),
style: TextStyle(
fontSize: 12 * AppConfig.fontSizeFactor,
fontWeight: FontWeight.bold,
color: theme.colorScheme.secondary,
),
),
),
),
),
),
),
row,
],
);
container = Material(type: MaterialType.transparency, child: container);
return Center(
child: Swipeable(
key: ValueKey(event.eventId),
background: const Padding(
padding: EdgeInsets.symmetric(horizontal: 12.0),
child: Center(
child: Icon(Icons.check_outlined),
),
),
direction: AppConfig.swipeRightToLeftToReply
? SwipeDirection.endToStart
: SwipeDirection.startToEnd,
onSwipe: (_) {},
child: Container(
constraints: const BoxConstraints(
maxWidth: FluffyThemes.columnWidth * 2.5,
),
padding: const EdgeInsets.only(
left: 8.0,
right: 8.0,
top: 4.0,
bottom: 4.0,
),
child: container,
),
),
);
}
}

@ -12,6 +12,7 @@ import 'package:fluffychat/pangea/choreographer/models/pangea_match_model.dart';
import 'package:fluffychat/pangea/choreographer/repo/full_text_translation_repo.dart';
import 'package:fluffychat/pangea/common/constants/model_keys.dart';
import 'package:fluffychat/pangea/events/event_wrappers/pangea_representation_event.dart';
import 'package:fluffychat/pangea/events/extensions/pangea_event_extension.dart';
import 'package:fluffychat/pangea/events/models/representation_content_model.dart';
import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart';
import 'package:fluffychat/pangea/spaces/models/space_model.dart';
@ -689,4 +690,6 @@ class PangeaMessageEvent {
/// Returns a list of [PracticeActivityEvent] for the user's active l2.
List<PracticeActivityEvent> get practiceActivities =>
l2Code == null ? [] : practiceActivitiesByLangCode(l2Code!);
bool get shouldShowToolbar => !event.isActivityMessage;
}

@ -88,4 +88,7 @@ extension PangeaEvent on Event {
waveform: waveform,
);
}
bool get isActivityMessage =>
content[ModelKey.messageTags] == ModelKey.messageTagActivityPlan;
}

@ -252,6 +252,7 @@ class MessageSelectionPositionerState extends State<MessageSelectionPositioner>
bool get showToolbarButtons =>
widget.pangeaMessageEvent != null &&
widget.pangeaMessageEvent!.shouldShowToolbar &&
widget.pangeaMessageEvent!.event.messageType == MessageTypes.Text;
double get _toolbarButtonsHeight =>
@ -374,6 +375,7 @@ class MessageSelectionPositionerState extends State<MessageSelectionPositioner>
overlayController: widget.overlayController,
chatController: widget.chatController,
hasReactions: _hasReactions,
shouldShowToolbarButtons: showToolbarButtons,
),
);
},
@ -436,6 +438,8 @@ class ToolbarOverlay extends StatelessWidget {
final Event? prevEvent;
final bool hasReactions;
final bool shouldShowToolbarButtons;
final PangeaMessageEvent? pangeaMessageEvent;
final MessageOverlayController overlayController;
final ChatController chatController;
@ -449,6 +453,7 @@ class ToolbarOverlay extends StatelessWidget {
required this.overlayController,
required this.chatController,
required this.hasReactions,
required this.shouldShowToolbarButtons,
this.pangeaMessageEvent,
this.nextEvent,
this.prevEvent,
@ -466,7 +471,8 @@ class ToolbarOverlay extends StatelessWidget {
? CrossAxisAlignment.end
: CrossAxisAlignment.start,
children: [
if (pangeaMessageEvent != null)
if (pangeaMessageEvent != null &&
pangeaMessageEvent!.shouldShowToolbar)
MessageToolbar(
pangeaMessageEvent: pangeaMessageEvent!,
overlayController: overlayController,
@ -498,10 +504,11 @@ class ToolbarOverlay extends StatelessWidget {
),
),
),
ToolbarButtons(
event: event,
overlayController: overlayController,
),
if (shouldShowToolbarButtons)
ToolbarButtons(
event: event,
overlayController: overlayController,
),
],
),
),

Loading…
Cancel
Save