💄 Optimize message indicator
This commit is contained in:
@@ -9,6 +9,7 @@ class MessageIndicators extends StatelessWidget {
|
|||||||
final MessageStatus? status;
|
final MessageStatus? status;
|
||||||
final bool isCurrentUser;
|
final bool isCurrentUser;
|
||||||
final Color textColor;
|
final Color textColor;
|
||||||
|
final EdgeInsets padding;
|
||||||
|
|
||||||
const MessageIndicators({
|
const MessageIndicators({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -16,26 +17,43 @@ class MessageIndicators extends StatelessWidget {
|
|||||||
this.status,
|
this.status,
|
||||||
required this.isCurrentUser,
|
required this.isCurrentUser,
|
||||||
required this.textColor,
|
required this.textColor,
|
||||||
|
this.padding = const EdgeInsets.only(left: 6),
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Row(
|
final children = <Widget>[];
|
||||||
spacing: 4,
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
if (editedAt != null) {
|
||||||
children: [
|
children.add(
|
||||||
if (editedAt != null)
|
|
||||||
Text(
|
Text(
|
||||||
'edited'.tr().toLowerCase(),
|
'edited'.tr().toLowerCase(),
|
||||||
style: TextStyle(fontSize: 11, color: textColor.withOpacity(0.7)),
|
style: TextStyle(fontSize: 11, color: textColor.withOpacity(0.7)),
|
||||||
),
|
),
|
||||||
if (isCurrentUser && status != null)
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCurrentUser && status != null && status != MessageStatus.sent) {
|
||||||
|
children.add(
|
||||||
_buildStatusIcon(
|
_buildStatusIcon(
|
||||||
context,
|
context,
|
||||||
status!,
|
status!,
|
||||||
textColor.withOpacity(0.7),
|
textColor.withOpacity(0.7),
|
||||||
).padding(bottom: 3),
|
).padding(bottom: 4),
|
||||||
],
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (children.isEmpty) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: padding,
|
||||||
|
child: Row(
|
||||||
|
spacing: 4,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: children,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,9 +64,18 @@ class MessageIndicators extends StatelessWidget {
|
|||||||
) {
|
) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case MessageStatus.pending:
|
case MessageStatus.pending:
|
||||||
return Icon(Icons.access_time, size: 12, color: textColor);
|
return SizedBox(
|
||||||
|
width: 10,
|
||||||
|
height: 10,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
strokeWidth: 2,
|
||||||
|
valueColor: AlwaysStoppedAnimation(textColor),
|
||||||
|
),
|
||||||
|
);
|
||||||
case MessageStatus.sent:
|
case MessageStatus.sent:
|
||||||
return Icon(Icons.check, size: 12, color: textColor);
|
// Sent status is hidden
|
||||||
|
return const SizedBox.shrink();
|
||||||
case MessageStatus.failed:
|
case MessageStatus.failed:
|
||||||
return Consumer(
|
return Consumer(
|
||||||
builder:
|
builder:
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -714,44 +715,11 @@ class MessageItemDisplayBubble extends HookConsumerWidget {
|
|||||||
renderingPadding: EdgeInsets.zero,
|
renderingPadding: EdgeInsets.zero,
|
||||||
maxWidth: 480,
|
maxWidth: 480,
|
||||||
),
|
),
|
||||||
if (progress != null && progress!.isNotEmpty)
|
FileUploadProgressWidget(
|
||||||
Column(
|
progress: progress,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
textColor: textColor,
|
||||||
spacing: 8,
|
hasContent:
|
||||||
children: [
|
remoteMessage.content?.isNotEmpty ?? false,
|
||||||
if ((remoteMessage.content?.isNotEmpty ?? false))
|
|
||||||
const Gap(0),
|
|
||||||
for (var entry in progress!.entries)
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'fileUploadingProgress'.tr(
|
|
||||||
args: [
|
|
||||||
(entry.key + 1).toString(),
|
|
||||||
entry.value.toStringAsFixed(1),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: textColor.withOpacity(0.8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Gap(4),
|
|
||||||
LinearProgressIndicator(
|
|
||||||
value: entry.value / 100,
|
|
||||||
backgroundColor:
|
|
||||||
Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.surfaceVariant,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
|
||||||
Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const Gap(0),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -833,6 +801,11 @@ class MessageItemDisplayIRC extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
Expanded(
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@@ -872,41 +845,19 @@ class MessageItemDisplayIRC extends HookConsumerWidget {
|
|||||||
renderingPadding: EdgeInsets.zero,
|
renderingPadding: EdgeInsets.zero,
|
||||||
maxWidth: 480,
|
maxWidth: 480,
|
||||||
),
|
),
|
||||||
if (progress != null && progress!.isNotEmpty)
|
FileUploadProgressWidget(
|
||||||
Column(
|
progress: progress,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
textColor: textColor,
|
||||||
spacing: 8,
|
hasContent: remoteMessage.content?.isNotEmpty ?? false,
|
||||||
children: [
|
|
||||||
if ((remoteMessage.content?.isNotEmpty ?? false))
|
|
||||||
const SizedBox.shrink(),
|
|
||||||
for (var entry in progress!.entries)
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'fileUploadingProgress'.tr(
|
|
||||||
args: [
|
|
||||||
(entry.key + 1).toString(),
|
|
||||||
entry.value.toStringAsFixed(1),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: textColor.withOpacity(0.8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Gap(4),
|
|
||||||
LinearProgressIndicator(
|
|
||||||
value: entry.value / 100,
|
|
||||||
backgroundColor:
|
|
||||||
Theme.of(context).colorScheme.surfaceVariant,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
|
||||||
Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
|
MessageIndicators(
|
||||||
|
editedAt: remoteMessage.editedAt,
|
||||||
|
status: message.status,
|
||||||
|
isCurrentUser: isCurrentUser,
|
||||||
|
textColor: textColor,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -971,7 +922,12 @@ class MessageItemDisplayDiscord extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Column(
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (remoteMessage.repliedMessageId != null)
|
if (remoteMessage.repliedMessageId != null)
|
||||||
@@ -1004,49 +960,28 @@ class MessageItemDisplayDiscord extends HookConsumerWidget {
|
|||||||
if (remoteMessage.meta['embeds'] != null &&
|
if (remoteMessage.meta['embeds'] != null &&
|
||||||
kMessageEnableEmbedTypes.contains(message.type))
|
kMessageEnableEmbedTypes.contains(message.type))
|
||||||
EmbedListWidget(
|
EmbedListWidget(
|
||||||
embeds: remoteMessage.meta['embeds'] as List<dynamic>,
|
embeds:
|
||||||
|
remoteMessage.meta['embeds']
|
||||||
|
as List<dynamic>,
|
||||||
isInteractive: true,
|
isInteractive: true,
|
||||||
isFullPost: false,
|
isFullPost: false,
|
||||||
renderingPadding: EdgeInsets.zero,
|
renderingPadding: EdgeInsets.zero,
|
||||||
maxWidth: 480,
|
maxWidth: 480,
|
||||||
),
|
),
|
||||||
if (progress != null && progress!.isNotEmpty)
|
FileUploadProgressWidget(
|
||||||
Column(
|
progress: progress,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
textColor: textColor,
|
||||||
spacing: 8,
|
hasContent:
|
||||||
children: [
|
remoteMessage.content?.isNotEmpty ?? false,
|
||||||
if ((remoteMessage.content?.isNotEmpty ?? false))
|
|
||||||
const SizedBox.shrink(),
|
|
||||||
for (var entry in progress!.entries)
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'fileUploadingProgress'.tr(
|
|
||||||
args: [
|
|
||||||
(entry.key + 1).toString(),
|
|
||||||
entry.value.toStringAsFixed(1),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: textColor.withOpacity(0.8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Gap(4),
|
|
||||||
LinearProgressIndicator(
|
|
||||||
value: entry.value / 100,
|
|
||||||
backgroundColor:
|
|
||||||
Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.surfaceVariant,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
|
||||||
Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
|
MessageIndicators(
|
||||||
|
editedAt: remoteMessage.editedAt,
|
||||||
|
status: message.status,
|
||||||
|
isCurrentUser: isCurrentUser,
|
||||||
|
textColor: textColor,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
).padding(left: kAvatarRadius * 2 + 8),
|
).padding(left: kAvatarRadius * 2 + 8),
|
||||||
@@ -1054,17 +989,14 @@ class MessageItemDisplayDiscord extends HookConsumerWidget {
|
|||||||
)
|
)
|
||||||
: Padding(
|
: Padding(
|
||||||
padding: EdgeInsets.only(left: kAvatarRadius * 2 + 8),
|
padding: EdgeInsets.only(left: kAvatarRadius * 2 + 8),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (showAvatar)
|
|
||||||
MessageSenderInfo(
|
|
||||||
sender: sender,
|
|
||||||
createdAt: message.createdAt,
|
|
||||||
textColor: textColor,
|
|
||||||
showAvatar: false,
|
|
||||||
isCompact: true,
|
|
||||||
),
|
|
||||||
if (remoteMessage.repliedMessageId != null)
|
if (remoteMessage.repliedMessageId != null)
|
||||||
MessageQuoteWidget(
|
MessageQuoteWidget(
|
||||||
message: message,
|
message: message,
|
||||||
@@ -1095,50 +1027,27 @@ class MessageItemDisplayDiscord extends HookConsumerWidget {
|
|||||||
if (remoteMessage.meta['embeds'] != null &&
|
if (remoteMessage.meta['embeds'] != null &&
|
||||||
kMessageEnableEmbedTypes.contains(message.type))
|
kMessageEnableEmbedTypes.contains(message.type))
|
||||||
EmbedListWidget(
|
EmbedListWidget(
|
||||||
embeds: remoteMessage.meta['embeds'] as List<dynamic>,
|
embeds:
|
||||||
|
remoteMessage.meta['embeds'] as List<dynamic>,
|
||||||
isInteractive: true,
|
isInteractive: true,
|
||||||
isFullPost: false,
|
isFullPost: false,
|
||||||
renderingPadding: EdgeInsets.zero,
|
renderingPadding: EdgeInsets.zero,
|
||||||
maxWidth: 480,
|
maxWidth: 480,
|
||||||
),
|
),
|
||||||
if (progress != null && progress!.isNotEmpty)
|
FileUploadProgressWidget(
|
||||||
Column(
|
progress: progress,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
textColor: textColor,
|
||||||
spacing: 8,
|
hasContent:
|
||||||
children: [
|
remoteMessage.content?.isNotEmpty ?? false,
|
||||||
if ((remoteMessage.content?.isNotEmpty ?? false))
|
|
||||||
const Gap(0),
|
|
||||||
for (var entry in progress!.entries)
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'fileUploadingProgress'.tr(
|
|
||||||
args: [
|
|
||||||
(entry.key + 1).toString(),
|
|
||||||
entry.value.toStringAsFixed(1),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: textColor.withOpacity(0.8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Gap(4),
|
|
||||||
LinearProgressIndicator(
|
|
||||||
value: entry.value / 100,
|
|
||||||
backgroundColor:
|
|
||||||
Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.surfaceVariant,
|
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
|
||||||
Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const Gap(0),
|
),
|
||||||
],
|
MessageIndicators(
|
||||||
|
editedAt: remoteMessage.editedAt,
|
||||||
|
status: message.status,
|
||||||
|
isCurrentUser: isCurrentUser,
|
||||||
|
textColor: textColor,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -1249,3 +1158,57 @@ class MessageQuoteWidget extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FileUploadProgressWidget extends StatelessWidget {
|
||||||
|
final Map<int, double>? progress;
|
||||||
|
final Color textColor;
|
||||||
|
final bool hasContent;
|
||||||
|
|
||||||
|
const FileUploadProgressWidget({
|
||||||
|
super.key,
|
||||||
|
required this.progress,
|
||||||
|
required this.textColor,
|
||||||
|
required this.hasContent,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (progress == null || progress!.isEmpty) return const SizedBox.shrink();
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
if (hasContent) const Gap(0),
|
||||||
|
for (var entry in progress!.entries)
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'fileUploadingProgress'.tr(
|
||||||
|
args: [
|
||||||
|
(entry.key + 1).toString(),
|
||||||
|
entry.value.toStringAsFixed(1),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: textColor.withOpacity(0.8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
LinearProgressIndicator(
|
||||||
|
value: entry.value,
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.surfaceVariant,
|
||||||
|
valueColor: AlwaysStoppedAnimation<Color>(
|
||||||
|
Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
trackGap: 0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Gap(0),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -52,7 +52,7 @@ class UploadMenu extends StatelessWidget {
|
|||||||
leadingIcon: Icon(item.icon),
|
leadingIcon: Icon(item.icon),
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
padding: WidgetStatePropertyAll(
|
padding: WidgetStatePropertyAll(
|
||||||
EdgeInsets.symmetric(horizontal: 16, vertical: 20),
|
EdgeInsets.only(left: 12, right: 16, top: 20, bottom: 20),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Text(item.textKey.tr()),
|
child: Text(item.textKey.tr()),
|
||||||
|
Reference in New Issue
Block a user