diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 4bde0f879..9424b01ae 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -2485,6 +2485,5 @@ "stickers": "Stickers", "discover": "Discover", "commandHint_ignore": "Ignore the given matrix ID", - "commandHint_unignore": "Unignore the given matrix ID", - "today": "Today" + "commandHint_unignore": "Unignore the given matrix ID" } \ No newline at end of file diff --git a/lib/pages/chat/chat_event_list.dart b/lib/pages/chat/chat_event_list.dart index 87b79ccdd..a35acb234 100644 --- a/lib/pages/chat/chat_event_list.dart +++ b/lib/pages/chat/chat_event_list.dart @@ -5,14 +5,12 @@ import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat/chat.dart'; -import 'package:fluffychat/pages/chat/events/date_separator.dart'; 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/utils/account_config.dart'; import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; -import 'package:fluffychat/utils/date_time_extension.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extension.dart'; import 'package:fluffychat/utils/platform_infos.dart'; @@ -108,8 +106,6 @@ class ChatEventList extends StatelessWidget { // The message at this index: final event = events[i]; - final nextEvent = i + 1 < events.length ? events[i + 1] : null; - final previousEvent = i > 0 ? events[i - 1] : null; final animateIn = animateInEventIndex != null && controller.timeline!.events.length > animateInEventIndex && event == controller.timeline!.events[animateInEventIndex]; @@ -118,48 +114,39 @@ class ChatEventList extends StatelessWidget { key: ValueKey(event.eventId), index: i, controller: controller.scrollController, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (nextEvent?.originServerTs - .isSameDate(event.originServerTs) != - true) - DateSeparator(date: event.originServerTs), - Message( - event, - animateIn: animateIn, - resetAnimateIn: () { - controller.animateInEventIndex = null; - }, - onSwipe: () => controller.replyAction(replyTo: event), - onInfoTab: controller.showEventInfo, - 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, - onSelect: controller.onSelectMessage, - scrollToEventId: (String eventId) => - controller.scrollToEventId(eventId), - longPressSelect: controller.selectedEvents.isNotEmpty, - selected: controller.selectedEvents - .any((e) => e.eventId == event.eventId), - timeline: controller.timeline!, - displayReadMarker: - controller.readMarkerEventId == event.eventId && - controller.timeline?.allowNewEvent == false, - nextEvent: nextEvent, - previousEvent: previousEvent, - avatarPresenceBackgroundColor: - hasWallpaper ? Colors.transparent : null, + child: Message( + event, + animateIn: animateIn, + resetAnimateIn: () { + controller.animateInEventIndex = null; + }, + onSwipe: () => controller.replyAction(replyTo: event), + onInfoTab: controller.showEventInfo, + 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, + onSelect: controller.onSelectMessage, + scrollToEventId: (String eventId) => + controller.scrollToEventId(eventId), + longPressSelect: controller.selectedEvents.isNotEmpty, + selected: controller.selectedEvents + .any((e) => e.eventId == event.eventId), + timeline: controller.timeline!, + displayReadMarker: + controller.readMarkerEventId == event.eventId && + controller.timeline?.allowNewEvent == false, + nextEvent: i + 1 < events.length ? events[i + 1] : null, + previousEvent: i > 0 ? events[i - 1] : null, + avatarPresenceBackgroundColor: + hasWallpaper ? Colors.transparent : null, ), ); }, diff --git a/lib/pages/chat/events/date_separator.dart b/lib/pages/chat/events/date_separator.dart deleted file mode 100644 index f8d9ef06f..000000000 --- a/lib/pages/chat/events/date_separator.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:fluffychat/config/app_config.dart'; -import 'package:fluffychat/utils/date_time_extension.dart'; - -class DateSeparator extends StatelessWidget { - final DateTime date; - const DateSeparator({required this.date, super.key}); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 12.0), - child: Row( - children: [ - Expanded( - child: Container( - height: 1, - color: Theme.of(context).dividerColor, - ), - ), - Padding( - padding: const EdgeInsets.all(12.0), - child: Text( - date.localizedTimeShort(context, dateOnly: true), - style: TextStyle( - color: Theme.of(context).colorScheme.secondary, - fontSize: 13 * AppConfig.fontSizeFactor, - ), - ), - ), - Expanded( - child: Container( - height: 1, - color: Theme.of(context).dividerColor, - ), - ), - ], - ), - ); - } -} diff --git a/lib/pages/chat/events/message.dart b/lib/pages/chat/events/message.dart index eb34058e7..fc711c861 100644 --- a/lib/pages/chat/events/message.dart +++ b/lib/pages/chat/events/message.dart @@ -203,53 +203,27 @@ class Message extends StatelessWidget { if (!nextEventSameSender) Padding( padding: const EdgeInsets.only(left: 8.0, bottom: 4), - child: Row( - mainAxisAlignment: ownMessage - ? MainAxisAlignment.end - : MainAxisAlignment.start, - children: [ - if (ownMessage || event.room.isDirectChat) - const SizedBox(height: 12) - else - FutureBuilder( + child: ownMessage || event.room.isDirectChat + ? const SizedBox(height: 12) + : FutureBuilder( future: event.fetchSenderUser(), builder: (context, snapshot) { final displayname = snapshot.data?.calcDisplayname() ?? event.senderFromMemoryOrFallback .calcDisplayname(); - return ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: FluffyThemes.columnWidth / 2, - ), - child: Text( - displayname, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 12, - color: (Theme.of(context).brightness == - Brightness.light - ? displayname.color - : displayname.lightColorText), - ), + return Text( + displayname, + style: TextStyle( + fontSize: 12, + color: (Theme.of(context).brightness == + Brightness.light + ? displayname.color + : displayname.lightColorText), ), ); }, ), - Text( - (ownMessage || event.room.isDirectChat - ? '' - : ' | ') + - event.originServerTs - .localizedTimeOfDay(context), - style: TextStyle( - fontSize: 12 * AppConfig.fontSizeFactor, - color: Theme.of(context).colorScheme.secondary, - ), - ), - ], - ), ), Container( alignment: alignment, @@ -389,12 +363,38 @@ class Message extends StatelessWidget { Widget container; final showReceiptsRow = event.hasAggregatedEvents(timeline, RelationshipTypes.reaction); - if (showReceiptsRow || selected || displayReadMarker) { + if (showReceiptsRow || displayTime || selected || displayReadMarker) { container = Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: ownMessage ? CrossAxisAlignment.end : CrossAxisAlignment.start, children: [ + if (displayTime || selected) + Padding( + padding: displayTime + ? const EdgeInsets.symmetric(vertical: 8.0) + : EdgeInsets.zero, + child: Center( + child: Material( + color: displayTime + ? Theme.of(context).colorScheme.background + : Theme.of(context) + .colorScheme + .background + .withOpacity(0.33), + borderRadius: + BorderRadius.circular(AppConfig.borderRadius / 2), + clipBehavior: Clip.antiAlias, + child: Padding( + padding: const EdgeInsets.all(4.0), + child: Text( + event.originServerTs.localizedTime(context), + style: TextStyle(fontSize: 13 * AppConfig.fontSizeFactor), + ), + ), + ), + ), + ), row, AnimatedSize( duration: FluffyThemes.animationDuration, diff --git a/lib/pages/chat_list/chat_list_view.dart b/lib/pages/chat_list/chat_list_view.dart index f9ffd9de2..96e2a4675 100644 --- a/lib/pages/chat_list/chat_list_view.dart +++ b/lib/pages/chat_list/chat_list_view.dart @@ -187,7 +187,12 @@ class ChatListView extends StatelessWidget { ? NavigationBar( elevation: 4, labelBehavior: - NavigationDestinationLabelBehavior.alwaysShow, + NavigationDestinationLabelBehavior.alwaysHide, + height: 64, + shadowColor: + Theme.of(context).colorScheme.onBackground, + surfaceTintColor: + Theme.of(context).colorScheme.background, selectedIndex: controller.selectedIndex, onDestinationSelected: controller.onDestinationSelected, diff --git a/lib/utils/date_time_extension.dart b/lib/utils/date_time_extension.dart index 72452b108..121eaf72e 100644 --- a/lib/utils/date_time_extension.dart +++ b/lib/utils/date_time_extension.dart @@ -45,7 +45,7 @@ extension DateTimeExtension on DateTime { /// Returns [localizedTimeOfDay()] if the ChatTime is today, the name of the week /// day if the ChatTime is this week and a date string else. - String localizedTimeShort(BuildContext context, {bool dateOnly = false}) { + String localizedTimeShort(BuildContext context) { final now = DateTime.now(); final sameYear = now.year == year; @@ -58,7 +58,7 @@ extension DateTimeExtension on DateTime { 1000 * 60 * 60 * 24 * 7; if (sameDay) { - return dateOnly ? L10n.of(context)!.today : localizedTimeOfDay(context); + return localizedTimeOfDay(context); } else if (sameWeek) { return DateFormat.EEEE(Localizations.localeOf(context).languageCode) .format(this); @@ -92,9 +92,5 @@ extension DateTimeExtension on DateTime { ); } - bool isSameDate(DateTime other) { - return year == other.year && month == other.month && day == other.day; - } - static String _z(int i) => i < 10 ? '0${i.toString()}' : i.toString(); }