design: Connect bubbles from same sender

pull/947/head
krille-chan 1 year ago
parent ca79beeddb
commit 292e6c8834
No known key found for this signature in database

@ -144,6 +144,7 @@ class ChatEventList extends StatelessWidget {
controller.readMarkerEventId == event.eventId && controller.readMarkerEventId == event.eventId &&
controller.timeline?.allowNewEvent == false, controller.timeline?.allowNewEvent == false,
nextEvent: i + 1 < events.length ? events[i + 1] : null, nextEvent: i + 1 < events.length ? events[i + 1] : null,
previousEvent: i > 0 ? events[i - 1] : null,
avatarPresenceBackgroundColor: avatarPresenceBackgroundColor:
hasWallpaper ? Colors.transparent : null, hasWallpaper ? Colors.transparent : null,
), ),

@ -21,6 +21,7 @@ import 'verification_request_content.dart';
class Message extends StatelessWidget { class Message extends StatelessWidget {
final Event event; final Event event;
final Event? nextEvent; final Event? nextEvent;
final Event? previousEvent;
final bool displayReadMarker; final bool displayReadMarker;
final void Function(Event) onSelect; final void Function(Event) onSelect;
final void Function(Event) onAvatarTab; final void Function(Event) onAvatarTab;
@ -38,6 +39,7 @@ class Message extends StatelessWidget {
const Message( const Message(
this.event, { this.event, {
this.nextEvent, this.nextEvent,
this.previousEvent,
this.displayReadMarker = false, this.displayReadMarker = false,
this.longPressSelect = false, this.longPressSelect = false,
required this.onSelect, required this.onSelect,
@ -80,31 +82,39 @@ class Message extends StatelessWidget {
final displayTime = event.type == EventTypes.RoomCreate || final displayTime = event.type == EventTypes.RoomCreate ||
nextEvent == null || nextEvent == null ||
!event.originServerTs.sameEnvironment(nextEvent!.originServerTs); !event.originServerTs.sameEnvironment(nextEvent!.originServerTs);
final sameSender = nextEvent != null && final nextEventSameSender = nextEvent != null &&
{ {
EventTypes.Message, EventTypes.Message,
EventTypes.Sticker, EventTypes.Sticker,
EventTypes.Encrypted, EventTypes.Encrypted,
}.contains(nextEvent!.type) && }.contains(nextEvent!.type) &&
nextEvent?.relationshipType == null &&
nextEvent!.senderId == event.senderId && nextEvent!.senderId == event.senderId &&
!displayTime; !displayTime;
final previousEventSameSender = previousEvent != null &&
{
EventTypes.Message,
EventTypes.Sticker,
EventTypes.Encrypted,
}.contains(previousEvent!.type) &&
previousEvent!.senderId == event.senderId;
final textColor = ownMessage final textColor = ownMessage
? Theme.of(context).colorScheme.onPrimaryContainer ? Theme.of(context).colorScheme.onPrimary
: Theme.of(context).colorScheme.onBackground; : Theme.of(context).colorScheme.onSurfaceVariant;
final rowMainAxisAlignment = final rowMainAxisAlignment =
ownMessage ? MainAxisAlignment.end : MainAxisAlignment.start; ownMessage ? MainAxisAlignment.end : MainAxisAlignment.start;
final displayEvent = event.getDisplayEvent(timeline); final displayEvent = event.getDisplayEvent(timeline);
const hardCorner = Radius.circular(4);
const roundedCorner = Radius.circular(AppConfig.borderRadius);
final borderRadius = BorderRadius.only( final borderRadius = BorderRadius.only(
topLeft: !ownMessage topLeft: !ownMessage && nextEventSameSender ? hardCorner : roundedCorner,
? const Radius.circular(4) topRight: ownMessage && nextEventSameSender ? hardCorner : roundedCorner,
: const Radius.circular(AppConfig.borderRadius), bottomLeft:
topRight: const Radius.circular(AppConfig.borderRadius), !ownMessage && previousEventSameSender ? hardCorner : roundedCorner,
bottomLeft: const Radius.circular(AppConfig.borderRadius), bottomRight:
bottomRight: ownMessage ownMessage && previousEventSameSender ? hardCorner : roundedCorner,
? const Radius.circular(4)
: const Radius.circular(AppConfig.borderRadius),
); );
final noBubble = { final noBubble = {
MessageTypes.Video, MessageTypes.Video,
@ -120,7 +130,7 @@ class Message extends StatelessWidget {
if (ownMessage) { if (ownMessage) {
color = displayEvent.status.isError color = displayEvent.status.isError
? Colors.redAccent ? Colors.redAccent
: Theme.of(context).colorScheme.primaryContainer; : Theme.of(context).colorScheme.primary;
} }
final resetAnimateIn = this.resetAnimateIn; final resetAnimateIn = this.resetAnimateIn;
@ -152,7 +162,7 @@ class Message extends StatelessWidget {
onChanged: (_) => onSelect(event), onChanged: (_) => onSelect(event),
), ),
) )
else if (sameSender || ownMessage) else if (nextEventSameSender || ownMessage)
SizedBox( SizedBox(
width: Avatar.defaultSize, width: Avatar.defaultSize,
child: Center( child: Center(
@ -189,7 +199,7 @@ class Message extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
if (!sameSender) if (!nextEventSameSender)
Padding( Padding(
padding: const EdgeInsets.only(left: 8.0, bottom: 4), padding: const EdgeInsets.only(left: 8.0, bottom: 4),
child: ownMessage || event.room.isDirectChat child: ownMessage || event.room.isDirectChat
@ -454,9 +464,11 @@ class Message extends StatelessWidget {
constraints: const BoxConstraints( constraints: const BoxConstraints(
maxWidth: FluffyThemes.columnWidth * 2.5, maxWidth: FluffyThemes.columnWidth * 2.5,
), ),
padding: const EdgeInsets.symmetric( padding: EdgeInsets.only(
horizontal: 8.0, left: 8.0,
vertical: 4.0, right: 8.0,
top: nextEventSameSender ? 1.0 : 4.0,
bottom: previousEventSameSender ? 1.0 : 4.0,
), ),
child: container, child: container,
), ),

@ -230,9 +230,7 @@ class SettingsStyleView extends StatelessWidget {
bottom: 12, bottom: 12,
), ),
child: Material( child: Material(
color: Theme.of(context) color: Theme.of(context).colorScheme.primary,
.colorScheme
.primaryContainer,
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(
AppConfig.borderRadius, AppConfig.borderRadius,
), ),
@ -244,9 +242,8 @@ class SettingsStyleView extends StatelessWidget {
child: Text( child: Text(
'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor', 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor',
style: TextStyle( style: TextStyle(
color: Theme.of(context) color:
.colorScheme Theme.of(context).colorScheme.onPrimary,
.onPrimaryContainer,
fontSize: AppConfig.messageFontSize * fontSize: AppConfig.messageFontSize *
AppConfig.fontSizeFactor, AppConfig.fontSizeFactor,
), ),

Loading…
Cancel
Save