refactor: Update to Dart 3.10 with . shorthands
This commit is contained in:
parent
75a37f3f7c
commit
1ea649f01e
167 changed files with 3351 additions and 3912 deletions
|
|
@ -100,12 +100,13 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
onPressed: () {
|
||||
audioPlayer.pause();
|
||||
audioPlayer.dispose();
|
||||
matrix.voiceMessageEventId.value =
|
||||
matrix.audioPlayer = null;
|
||||
matrix.voiceMessageEventId.value = matrix.audioPlayer =
|
||||
null;
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
ScaffoldMessenger.of(matrix.context)
|
||||
.clearMaterialBanners();
|
||||
ScaffoldMessenger.of(
|
||||
matrix.context,
|
||||
).clearMaterialBanners();
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.close_outlined),
|
||||
|
|
@ -128,8 +129,8 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
});
|
||||
final currentPlayer =
|
||||
matrix.voiceMessageEventId.value != widget.event.eventId
|
||||
? null
|
||||
: matrix.audioPlayer;
|
||||
? null
|
||||
: matrix.audioPlayer;
|
||||
if (currentPlayer != null) {
|
||||
if (currentPlayer.isAtEndPosition) {
|
||||
currentPlayer.seek(Duration.zero);
|
||||
|
|
@ -158,8 +159,9 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
? (progress) {
|
||||
final progressPercentage = progress / fileSize;
|
||||
setState(() {
|
||||
_downloadProgress =
|
||||
progressPercentage < 1 ? progressPercentage : null;
|
||||
_downloadProgress = progressPercentage < 1
|
||||
? progressPercentage
|
||||
: null;
|
||||
});
|
||||
}
|
||||
: null,
|
||||
|
|
@ -190,11 +192,9 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
});
|
||||
} catch (e, s) {
|
||||
Logs().v('Could not download audio file', e, s);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(e.toLocalizedString(context)),
|
||||
),
|
||||
);
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text(e.toLocalizedString(context))));
|
||||
rethrow;
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
|
|
@ -209,9 +209,8 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
}
|
||||
|
||||
audioPlayer.play().onError(
|
||||
ErrorReporter(context, 'Unable to play audio message')
|
||||
.onErrorCallback,
|
||||
);
|
||||
ErrorReporter(context, 'Unable to play audio message').onErrorCallback,
|
||||
);
|
||||
}
|
||||
|
||||
void _toggleSpeed() async {
|
||||
|
|
@ -289,8 +288,9 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
return ValueListenableBuilder(
|
||||
valueListenable: matrix.voiceMessageEventId,
|
||||
builder: (context, eventId, _) {
|
||||
final audioPlayer =
|
||||
eventId != widget.event.eventId ? null : matrix.audioPlayer;
|
||||
final audioPlayer = eventId != widget.event.eventId
|
||||
? null
|
||||
: matrix.audioPlayer;
|
||||
|
||||
final fileDescription = widget.event.fileDescription;
|
||||
|
||||
|
|
@ -317,15 +317,15 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
return Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: .min,
|
||||
crossAxisAlignment: .start,
|
||||
children: [
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: FluffyThemes.columnWidth,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
width: buttonSize,
|
||||
|
|
@ -366,9 +366,11 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
),
|
||||
child: Row(
|
||||
children: [
|
||||
for (var i = 0;
|
||||
i < AudioPlayerWidget.wavesCount;
|
||||
i++)
|
||||
for (
|
||||
var i = 0;
|
||||
i < AudioPlayerWidget.wavesCount;
|
||||
i++
|
||||
)
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 32,
|
||||
|
|
@ -376,13 +378,14 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
child: Container(
|
||||
margin:
|
||||
const EdgeInsets.symmetric(
|
||||
horizontal: 1,
|
||||
),
|
||||
horizontal: 1,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: i < wavePosition
|
||||
? widget.color
|
||||
: widget.color
|
||||
.withAlpha(128),
|
||||
: widget.color.withAlpha(
|
||||
128,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius.circular(64),
|
||||
),
|
||||
|
|
@ -396,7 +399,8 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
SizedBox(
|
||||
height: 32,
|
||||
child: Slider(
|
||||
thumbColor: widget.event.senderId ==
|
||||
thumbColor:
|
||||
widget.event.senderId ==
|
||||
widget.event.room.client.userID
|
||||
? theme.colorScheme.onPrimary
|
||||
: theme.colorScheme.primary,
|
||||
|
|
@ -425,10 +429,7 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
width: 36,
|
||||
child: Text(
|
||||
statusText,
|
||||
style: TextStyle(
|
||||
color: widget.color,
|
||||
fontSize: 12,
|
||||
),
|
||||
style: TextStyle(color: widget.color, fontSize: 12),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
|
|
@ -442,11 +443,13 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
),
|
||||
secondChild: Material(
|
||||
color: widget.color.withAlpha(64),
|
||||
borderRadius:
|
||||
BorderRadius.circular(AppConfig.borderRadius),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConfig.borderRadius,
|
||||
),
|
||||
child: InkWell(
|
||||
borderRadius:
|
||||
BorderRadius.circular(AppConfig.borderRadius),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConfig.borderRadius,
|
||||
),
|
||||
onTap: _toggleSpeed,
|
||||
child: SizedBox(
|
||||
width: 32,
|
||||
|
|
@ -481,8 +484,9 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
),
|
||||
child: Linkify(
|
||||
text: fileDescription,
|
||||
textScaleFactor:
|
||||
MediaQuery.textScalerOf(context).scale(1),
|
||||
textScaleFactor: MediaQuery.textScalerOf(
|
||||
context,
|
||||
).scale(1),
|
||||
style: TextStyle(
|
||||
color: widget.color,
|
||||
fontSize: widget.fontSize,
|
||||
|
|
|
|||
|
|
@ -37,13 +37,10 @@ class _CuteContentState extends State<CuteContent> {
|
|||
return GestureDetector(
|
||||
onTap: addOverlay,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: .min,
|
||||
mainAxisAlignment: .center,
|
||||
children: [
|
||||
Text(
|
||||
widget.event.text,
|
||||
style: const TextStyle(fontSize: 150),
|
||||
),
|
||||
Text(widget.event.text, style: const TextStyle(fontSize: 150)),
|
||||
if (label != null) Text(label),
|
||||
],
|
||||
),
|
||||
|
|
@ -112,10 +109,7 @@ class _CuteEventOverlayState extends State<CuteEventOverlay>
|
|||
with TickerProviderStateMixin {
|
||||
final List<Size> items = List.generate(
|
||||
50,
|
||||
(index) => Size(
|
||||
Random().nextDouble(),
|
||||
4 + (Random().nextDouble() * 4),
|
||||
),
|
||||
(index) => Size(Random().nextDouble(), 4 + (Random().nextDouble() * 4)),
|
||||
);
|
||||
|
||||
AnimationController? controller;
|
||||
|
|
@ -150,14 +144,13 @@ class _CuteEventOverlayState extends State<CuteEventOverlay>
|
|||
.map(
|
||||
(position) => Positioned(
|
||||
left: position.width * width,
|
||||
bottom: (height *
|
||||
bottom:
|
||||
(height *
|
||||
.25 *
|
||||
position.height *
|
||||
(controller?.value ?? 0)) -
|
||||
_CuteOverlayContent.size,
|
||||
child: _CuteOverlayContent(
|
||||
emoji: widget.emoji,
|
||||
),
|
||||
child: _CuteOverlayContent(emoji: widget.emoji),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
|
|
@ -186,10 +179,7 @@ class _CuteOverlayContent extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return SizedBox.square(
|
||||
dimension: size,
|
||||
child: Text(
|
||||
emoji,
|
||||
style: const TextStyle(fontSize: 48),
|
||||
),
|
||||
child: Text(emoji, style: const TextStyle(fontSize: 48)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,8 @@ class HtmlMessage extends StatelessWidget {
|
|||
if (node is! dom.Element) {
|
||||
return TextSpan(text: node.text);
|
||||
}
|
||||
final style = atomOneDarkTheme[node.className.split('-').last] ??
|
||||
final style =
|
||||
atomOneDarkTheme[node.className.split('-').last] ??
|
||||
atomOneDarkTheme['root'];
|
||||
|
||||
return TextSpan(
|
||||
|
|
@ -151,11 +152,7 @@ class HtmlMessage extends StatelessWidget {
|
|||
}
|
||||
|
||||
/// Transforms a Node to an InlineSpan.
|
||||
InlineSpan _renderHtml(
|
||||
dom.Node node,
|
||||
BuildContext context, {
|
||||
int depth = 1,
|
||||
}) {
|
||||
InlineSpan _renderHtml(dom.Node node, BuildContext context, {int depth = 1}) {
|
||||
// We must not render elements nested more than 100 elements deep:
|
||||
if (depth >= 100) return const TextSpan();
|
||||
|
||||
|
|
@ -245,9 +242,9 @@ class HtmlMessage extends StatelessWidget {
|
|||
final isCheckbox = node.className == 'task-list-item';
|
||||
final checkboxIndex = isCheckbox
|
||||
? node.rootElement
|
||||
.getElementsByClassName('task-list-item')
|
||||
.indexOf(node) +
|
||||
1
|
||||
.getElementsByClassName('task-list-item')
|
||||
.indexOf(node) +
|
||||
1
|
||||
: null;
|
||||
final checkedByReaction = !isCheckbox
|
||||
? null
|
||||
|
|
@ -283,7 +280,8 @@ class HtmlMessage extends StatelessWidget {
|
|||
activeColor: textColor.withAlpha(64),
|
||||
value:
|
||||
staticallyChecked || checkedByReaction != null,
|
||||
onChanged: eventId == null ||
|
||||
onChanged:
|
||||
eventId == null ||
|
||||
checkboxIndex == null ||
|
||||
staticallyChecked ||
|
||||
!room.canSendDefaultMessages ||
|
||||
|
|
@ -292,25 +290,21 @@ class HtmlMessage extends StatelessWidget {
|
|||
room.client.userID)
|
||||
? null
|
||||
: (_) => showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => checkedByReaction != null
|
||||
? room.redactEvent(
|
||||
checkedByReaction.eventId,
|
||||
)
|
||||
: room.checkCheckbox(
|
||||
eventId,
|
||||
checkboxIndex,
|
||||
),
|
||||
),
|
||||
context: context,
|
||||
future: () => checkedByReaction != null
|
||||
? room.redactEvent(
|
||||
checkedByReaction.eventId,
|
||||
)
|
||||
: room.checkCheckbox(
|
||||
eventId,
|
||||
checkboxIndex,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
..._renderWithLineBreaks(
|
||||
node.nodes,
|
||||
context,
|
||||
depth: depth,
|
||||
),
|
||||
..._renderWithLineBreaks(node.nodes, context, depth: depth),
|
||||
],
|
||||
style: TextStyle(fontSize: fontSize, color: textColor),
|
||||
),
|
||||
|
|
@ -322,12 +316,7 @@ class HtmlMessage extends StatelessWidget {
|
|||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
left: BorderSide(
|
||||
color: textColor,
|
||||
width: 5,
|
||||
),
|
||||
),
|
||||
border: Border(left: BorderSide(color: textColor, width: 5)),
|
||||
),
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
|
|
@ -347,7 +336,8 @@ class HtmlMessage extends StatelessWidget {
|
|||
);
|
||||
case 'code':
|
||||
final isInline = node.parent?.localName != 'pre';
|
||||
final lang = node.className
|
||||
final lang =
|
||||
node.className
|
||||
.split(' ')
|
||||
.singleWhereOrNull(
|
||||
(className) => className.startsWith('language-'),
|
||||
|
|
@ -355,8 +345,9 @@ class HtmlMessage extends StatelessWidget {
|
|||
?.split('language-')
|
||||
.last ??
|
||||
'md';
|
||||
final highlightedHtml =
|
||||
highlight.parse(node.text, language: lang).toHtml();
|
||||
final highlightedHtml = highlight
|
||||
.parse(node.text, language: lang)
|
||||
.toHtml();
|
||||
final element = parser.parse(highlightedHtml).body;
|
||||
if (element == null) {
|
||||
return const TextSpan(text: 'Unable to render code block!');
|
||||
|
|
@ -372,14 +363,9 @@ class HtmlMessage extends StatelessWidget {
|
|||
child: Padding(
|
||||
padding: isInline
|
||||
? const EdgeInsets.symmetric(horizontal: 4.0)
|
||||
: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
children: [_renderCodeBlockNode(element)],
|
||||
),
|
||||
TextSpan(children: [_renderCodeBlockNode(element)]),
|
||||
selectionColor: hightlightTextColor.withAlpha(128),
|
||||
),
|
||||
),
|
||||
|
|
@ -448,10 +434,7 @@ class HtmlMessage extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: fontSize,
|
||||
color: textColor,
|
||||
),
|
||||
style: TextStyle(fontSize: fontSize, color: textColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -489,17 +472,13 @@ class HtmlMessage extends StatelessWidget {
|
|||
default:
|
||||
return TextSpan(
|
||||
style: switch (node.localName) {
|
||||
'body' => TextStyle(
|
||||
fontSize: fontSize,
|
||||
color: textColor,
|
||||
),
|
||||
'body' => TextStyle(fontSize: fontSize, color: textColor),
|
||||
'a' => linkStyle,
|
||||
'strong' => const TextStyle(fontWeight: FontWeight.bold),
|
||||
'em' || 'i' => const TextStyle(fontStyle: FontStyle.italic),
|
||||
'del' ||
|
||||
's' ||
|
||||
'strikethrough' =>
|
||||
const TextStyle(decoration: TextDecoration.lineThrough),
|
||||
'del' || 's' || 'strikethrough' => const TextStyle(
|
||||
decoration: TextDecoration.lineThrough,
|
||||
),
|
||||
'u' => const TextStyle(decoration: TextDecoration.underline),
|
||||
'h1' => TextStyle(fontSize: fontSize * 1.6, height: 2),
|
||||
'h2' => TextStyle(fontSize: fontSize * 1.5, height: 2),
|
||||
|
|
@ -508,22 +487,19 @@ class HtmlMessage extends StatelessWidget {
|
|||
'h5' => TextStyle(fontSize: fontSize * 1.2, height: 1.75),
|
||||
'h6' => TextStyle(fontSize: fontSize * 1.1, height: 1.5),
|
||||
'span' => TextStyle(
|
||||
color: node.attributes['color']?.hexToColor ??
|
||||
node.attributes['data-mx-color']?.hexToColor ??
|
||||
textColor,
|
||||
backgroundColor:
|
||||
node.attributes['data-mx-bg-color']?.hexToColor,
|
||||
),
|
||||
'sup' =>
|
||||
const TextStyle(fontFeatures: [FontFeature.superscripts()]),
|
||||
color:
|
||||
node.attributes['color']?.hexToColor ??
|
||||
node.attributes['data-mx-color']?.hexToColor ??
|
||||
textColor,
|
||||
backgroundColor: node.attributes['data-mx-bg-color']?.hexToColor,
|
||||
),
|
||||
'sup' => const TextStyle(
|
||||
fontFeatures: [FontFeature.superscripts()],
|
||||
),
|
||||
'sub' => const TextStyle(fontFeatures: [FontFeature.subscripts()]),
|
||||
_ => null,
|
||||
},
|
||||
children: _renderWithLineBreaks(
|
||||
node.nodes,
|
||||
context,
|
||||
depth: depth,
|
||||
),
|
||||
children: _renderWithLineBreaks(node.nodes, context, depth: depth),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -533,10 +509,7 @@ class HtmlMessage extends StatelessWidget {
|
|||
final element = parser.parse(html).body ?? dom.Element.html('');
|
||||
return Text.rich(
|
||||
_renderHtml(element, context),
|
||||
style: TextStyle(
|
||||
fontSize: fontSize,
|
||||
color: textColor,
|
||||
),
|
||||
style: TextStyle(fontSize: fontSize, color: textColor),
|
||||
maxLines: limitHeight ? 64 : null,
|
||||
overflow: TextOverflow.fade,
|
||||
selectionColor: textColor.withAlpha(128),
|
||||
|
|
@ -568,13 +541,9 @@ class MatrixPill extends StatelessWidget {
|
|||
splashColor: Colors.transparent,
|
||||
onTap: UrlLauncher(outerContext, uri).launchUrl,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
Avatar(
|
||||
mxContent: avatar,
|
||||
name: name,
|
||||
size: 16,
|
||||
),
|
||||
Avatar(mxContent: avatar, name: name, size: 16),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
name,
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ class ImageBubble extends StatelessWidget {
|
|||
Widget _buildPlaceholder(BuildContext context) {
|
||||
final String blurHashString =
|
||||
event.infoMap['xyz.amorgan.blurhash'] is String
|
||||
? event.infoMap['xyz.amorgan.blurhash']
|
||||
: 'LEHV6nWB2yk8pyo0adR*.7kCMdnj';
|
||||
? event.infoMap['xyz.amorgan.blurhash']
|
||||
: 'LEHV6nWB2yk8pyo0adR*.7kCMdnj';
|
||||
return SizedBox(
|
||||
width: width,
|
||||
height: height,
|
||||
|
|
@ -68,11 +68,8 @@ class ImageBubble extends StatelessWidget {
|
|||
if (!tapToView) return;
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => ImageViewer(
|
||||
event,
|
||||
timeline: timeline,
|
||||
outerContext: context,
|
||||
),
|
||||
builder: (_) =>
|
||||
ImageViewer(event, timeline: timeline, outerContext: context),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +91,7 @@ class ImageBubble extends StatelessWidget {
|
|||
}
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
spacing: 8,
|
||||
children: [
|
||||
Material(
|
||||
|
|
@ -131,22 +128,21 @@ class ImageBubble extends StatelessWidget {
|
|||
SizedBox(
|
||||
width: width,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
child: Linkify(
|
||||
text: fileDescription,
|
||||
textScaleFactor: MediaQuery.textScalerOf(context).scale(1),
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
fontSize: AppSettings.fontSizeFactor.value *
|
||||
fontSize:
|
||||
AppSettings.fontSizeFactor.value *
|
||||
AppConfig.messageFontSize,
|
||||
),
|
||||
options: const LinkifyOptions(humanize: false),
|
||||
linkStyle: TextStyle(
|
||||
color: linkColor,
|
||||
fontSize: AppSettings.fontSizeFactor.value *
|
||||
fontSize:
|
||||
AppSettings.fontSizeFactor.value *
|
||||
AppConfig.messageFontSize,
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: linkColor,
|
||||
|
|
|
|||
|
|
@ -107,10 +107,12 @@ class Message extends StatelessWidget {
|
|||
final alignment = ownMessage ? Alignment.topRight : Alignment.topLeft;
|
||||
|
||||
var color = theme.colorScheme.surfaceContainerHigh;
|
||||
final displayTime = event.type == EventTypes.RoomCreate ||
|
||||
final displayTime =
|
||||
event.type == EventTypes.RoomCreate ||
|
||||
nextEvent == null ||
|
||||
!event.originServerTs.sameEnvironment(nextEvent!.originServerTs);
|
||||
final nextEventSameSender = nextEvent != null &&
|
||||
final nextEventSameSender =
|
||||
nextEvent != null &&
|
||||
{
|
||||
EventTypes.Message,
|
||||
EventTypes.Sticker,
|
||||
|
|
@ -119,7 +121,8 @@ class Message extends StatelessWidget {
|
|||
nextEvent!.senderId == event.senderId &&
|
||||
!displayTime;
|
||||
|
||||
final previousEventSameSender = previousEvent != null &&
|
||||
final previousEventSameSender =
|
||||
previousEvent != null &&
|
||||
{
|
||||
EventTypes.Message,
|
||||
EventTypes.Sticker,
|
||||
|
|
@ -128,17 +131,19 @@ class Message extends StatelessWidget {
|
|||
previousEvent!.senderId == event.senderId &&
|
||||
previousEvent!.originServerTs.sameEnvironment(event.originServerTs);
|
||||
|
||||
final textColor =
|
||||
ownMessage ? theme.onBubbleColor : theme.colorScheme.onSurface;
|
||||
final textColor = ownMessage
|
||||
? theme.onBubbleColor
|
||||
: theme.colorScheme.onSurface;
|
||||
|
||||
final linkColor = ownMessage
|
||||
? theme.brightness == Brightness.light
|
||||
? theme.colorScheme.primaryFixed
|
||||
: theme.colorScheme.onTertiaryContainer
|
||||
? theme.colorScheme.primaryFixed
|
||||
: theme.colorScheme.onTertiaryContainer
|
||||
: theme.colorScheme.primary;
|
||||
|
||||
final rowMainAxisAlignment =
|
||||
ownMessage ? MainAxisAlignment.end : MainAxisAlignment.start;
|
||||
final rowMainAxisAlignment = ownMessage
|
||||
? MainAxisAlignment.end
|
||||
: MainAxisAlignment.start;
|
||||
|
||||
final displayEvent = event.getDisplayEvent(timeline);
|
||||
const hardCorner = Radius.circular(4);
|
||||
|
|
@ -146,12 +151,15 @@ class Message extends StatelessWidget {
|
|||
final borderRadius = BorderRadius.only(
|
||||
topLeft: !ownMessage && nextEventSameSender ? hardCorner : roundedCorner,
|
||||
topRight: ownMessage && nextEventSameSender ? hardCorner : roundedCorner,
|
||||
bottomLeft:
|
||||
!ownMessage && previousEventSameSender ? hardCorner : roundedCorner,
|
||||
bottomRight:
|
||||
ownMessage && previousEventSameSender ? hardCorner : roundedCorner,
|
||||
bottomLeft: !ownMessage && previousEventSameSender
|
||||
? hardCorner
|
||||
: roundedCorner,
|
||||
bottomRight: ownMessage && previousEventSameSender
|
||||
? hardCorner
|
||||
: roundedCorner,
|
||||
);
|
||||
final noBubble = ({
|
||||
final noBubble =
|
||||
({
|
||||
MessageTypes.Video,
|
||||
MessageTypes.Image,
|
||||
MessageTypes.Sticker,
|
||||
|
|
@ -165,8 +173,9 @@ class Message extends StatelessWidget {
|
|||
event.numberEmotes <= 3);
|
||||
|
||||
if (ownMessage) {
|
||||
color =
|
||||
displayEvent.status.isError ? Colors.redAccent : theme.bubbleColor;
|
||||
color = displayEvent.status.isError
|
||||
? Colors.redAccent
|
||||
: theme.bubbleColor;
|
||||
}
|
||||
|
||||
final resetAnimateIn = this.resetAnimateIn;
|
||||
|
|
@ -176,10 +185,7 @@ class Message extends StatelessWidget {
|
|||
if (singleSelected) {
|
||||
sentReactions.addAll(
|
||||
event
|
||||
.aggregatedEvents(
|
||||
timeline,
|
||||
RelationshipTypes.reaction,
|
||||
)
|
||||
.aggregatedEvents(timeline, RelationshipTypes.reaction)
|
||||
.where(
|
||||
(event) =>
|
||||
event.senderId == event.room.client.userID &&
|
||||
|
|
@ -194,11 +200,15 @@ class Message extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
final showReceiptsRow =
|
||||
event.hasAggregatedEvents(timeline, RelationshipTypes.reaction);
|
||||
final showReceiptsRow = event.hasAggregatedEvents(
|
||||
timeline,
|
||||
RelationshipTypes.reaction,
|
||||
);
|
||||
|
||||
final threadChildren =
|
||||
event.aggregatedEvents(timeline, RelationshipTypes.thread);
|
||||
final threadChildren = event.aggregatedEvents(
|
||||
timeline,
|
||||
RelationshipTypes.thread,
|
||||
);
|
||||
|
||||
final showReactionPicker =
|
||||
singleSelected && event.room.canSendDefaultMessages;
|
||||
|
|
@ -210,9 +220,7 @@ class Message extends StatelessWidget {
|
|||
key: ValueKey(event.eventId),
|
||||
background: const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12.0),
|
||||
child: Center(
|
||||
child: Icon(Icons.check_outlined),
|
||||
),
|
||||
child: Center(child: Icon(Icons.check_outlined)),
|
||||
),
|
||||
direction: AppSettings.swipeRightToLeftToReply.value
|
||||
? SwipeDirection.endToStart
|
||||
|
|
@ -229,9 +237,8 @@ class Message extends StatelessWidget {
|
|||
bottom: previousEventSameSender ? 1.0 : 4.0,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment:
|
||||
ownMessage ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
||||
mainAxisSize: .min,
|
||||
crossAxisAlignment: ownMessage ? .end : .start,
|
||||
children: <Widget>[
|
||||
if (displayTime || selected)
|
||||
Padding(
|
||||
|
|
@ -242,8 +249,9 @@ class Message extends StatelessWidget {
|
|||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 4.0),
|
||||
child: Material(
|
||||
borderRadius:
|
||||
BorderRadius.circular(AppConfig.borderRadius * 2),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConfig.borderRadius * 2,
|
||||
),
|
||||
color: theme.colorScheme.surface.withAlpha(128),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
|
|
@ -305,13 +313,13 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
color: selected || highlightMarker
|
||||
? theme.colorScheme.secondaryContainer
|
||||
.withAlpha(128)
|
||||
.withAlpha(128)
|
||||
: Colors.transparent,
|
||||
),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: .start,
|
||||
mainAxisAlignment: rowMainAxisAlignment,
|
||||
children: [
|
||||
if (longPressSelect && !event.redacted)
|
||||
|
|
@ -336,18 +344,17 @@ class Message extends StatelessWidget {
|
|||
child: SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
child: event.status ==
|
||||
EventStatus.error
|
||||
child:
|
||||
event.status == EventStatus.error
|
||||
? const Icon(
|
||||
Icons.error,
|
||||
color: Colors.red,
|
||||
)
|
||||
: event.fileSendingStatus != null
|
||||
? const CircularProgressIndicator
|
||||
.adaptive(
|
||||
strokeWidth: 1,
|
||||
)
|
||||
: null,
|
||||
? const CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 1,
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -355,17 +362,18 @@ class Message extends StatelessWidget {
|
|||
FutureBuilder<User?>(
|
||||
future: event.fetchSenderUser(),
|
||||
builder: (context, snapshot) {
|
||||
final user = snapshot.data ??
|
||||
final user =
|
||||
snapshot.data ??
|
||||
event.senderFromMemoryOrFallback;
|
||||
return Avatar(
|
||||
mxContent: user.avatarUrl,
|
||||
name: user.calcDisplayname(),
|
||||
onTap: () =>
|
||||
showMemberActionsPopupMenu(
|
||||
context: context,
|
||||
user: user,
|
||||
onMention: onMention,
|
||||
),
|
||||
context: context,
|
||||
user: user,
|
||||
onMention: onMention,
|
||||
),
|
||||
presenceUserId: user.stateKey,
|
||||
presenceBackgroundColor: wallpaperMode
|
||||
? Colors.transparent
|
||||
|
|
@ -375,9 +383,8 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: .start,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
if (!nextEventSameSender)
|
||||
Padding(
|
||||
|
|
@ -385,16 +392,16 @@ class Message extends StatelessWidget {
|
|||
left: 8.0,
|
||||
bottom: 4,
|
||||
),
|
||||
child: ownMessage ||
|
||||
child:
|
||||
ownMessage ||
|
||||
event.room.isDirectChat
|
||||
? const SizedBox(height: 12)
|
||||
: FutureBuilder<User?>(
|
||||
future:
|
||||
event.fetchSenderUser(),
|
||||
builder:
|
||||
(context, snapshot) {
|
||||
final displayname = snapshot
|
||||
.data
|
||||
future: event
|
||||
.fetchSenderUser(),
|
||||
builder: (context, snapshot) {
|
||||
final displayname =
|
||||
snapshot.data
|
||||
?.calcDisplayname() ??
|
||||
event
|
||||
.senderFromMemoryOrFallback
|
||||
|
|
@ -405,29 +412,30 @@ class Message extends StatelessWidget {
|
|||
fontSize: 11,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
color: (theme.brightness ==
|
||||
color:
|
||||
(theme.brightness ==
|
||||
Brightness
|
||||
.light
|
||||
? displayname
|
||||
.color
|
||||
.color
|
||||
: displayname
|
||||
.lightColorText),
|
||||
.lightColorText),
|
||||
shadows:
|
||||
!wallpaperMode
|
||||
? null
|
||||
: [
|
||||
const Shadow(
|
||||
offset:
|
||||
Offset(
|
||||
? null
|
||||
: [
|
||||
const Shadow(
|
||||
offset:
|
||||
Offset(
|
||||
0.0,
|
||||
0.0,
|
||||
),
|
||||
blurRadius:
|
||||
3,
|
||||
color: Colors
|
||||
.black,
|
||||
),
|
||||
],
|
||||
blurRadius:
|
||||
3,
|
||||
color: Colors
|
||||
.black,
|
||||
),
|
||||
],
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow
|
||||
|
|
@ -438,25 +446,25 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
Container(
|
||||
alignment: alignment,
|
||||
padding:
|
||||
const EdgeInsets.only(left: 8),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 8,
|
||||
),
|
||||
child: GestureDetector(
|
||||
onLongPress: longPressSelect
|
||||
? null
|
||||
: () {
|
||||
HapticFeedback
|
||||
.heavyImpact();
|
||||
HapticFeedback.heavyImpact();
|
||||
onSelect(event);
|
||||
},
|
||||
child: AnimatedOpacity(
|
||||
opacity: animateIn
|
||||
? 0
|
||||
: event.messageType ==
|
||||
MessageTypes
|
||||
.BadEncrypted ||
|
||||
event.status.isSending
|
||||
? 0.5
|
||||
: 1,
|
||||
MessageTypes
|
||||
.BadEncrypted ||
|
||||
event.status.isSending
|
||||
? 0.5
|
||||
: 1,
|
||||
duration: FluffyThemes
|
||||
.animationDuration,
|
||||
curve:
|
||||
|
|
@ -471,7 +479,8 @@ class Message extends StatelessWidget {
|
|||
clipBehavior: Clip.antiAlias,
|
||||
child: BubbleBackground(
|
||||
colors: colors,
|
||||
ignore: noBubble ||
|
||||
ignore:
|
||||
noBubble ||
|
||||
!ownMessage ||
|
||||
MediaQuery.highContrastOf(
|
||||
context,
|
||||
|
|
@ -482,24 +491,24 @@ class Message extends StatelessWidget {
|
|||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
AppConfig.borderRadius,
|
||||
),
|
||||
AppConfig
|
||||
.borderRadius,
|
||||
),
|
||||
),
|
||||
constraints:
|
||||
const BoxConstraints(
|
||||
maxWidth: FluffyThemes
|
||||
.columnWidth *
|
||||
1.5,
|
||||
),
|
||||
maxWidth:
|
||||
FluffyThemes
|
||||
.columnWidth *
|
||||
1.5,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
children: <Widget>[
|
||||
if (event
|
||||
.inReplyToEventId(
|
||||
if (event.inReplyToEventId(
|
||||
includingFallback:
|
||||
false,
|
||||
) !=
|
||||
|
|
@ -507,21 +516,23 @@ class Message extends StatelessWidget {
|
|||
FutureBuilder<Event?>(
|
||||
future: event
|
||||
.getReplyEvent(
|
||||
timeline,
|
||||
),
|
||||
builder: (
|
||||
BuildContext
|
||||
timeline,
|
||||
),
|
||||
builder:
|
||||
(
|
||||
BuildContext
|
||||
context,
|
||||
snapshot,
|
||||
) {
|
||||
final replyEvent =
|
||||
snapshot
|
||||
snapshot,
|
||||
) {
|
||||
final replyEvent =
|
||||
snapshot
|
||||
.hasData
|
||||
? snapshot
|
||||
.data!
|
||||
.data!
|
||||
: Event(
|
||||
eventId:
|
||||
event.inReplyToEventId() ?? '\$fake_event_id',
|
||||
event.inReplyToEventId() ??
|
||||
'\$fake_event_id',
|
||||
content: {
|
||||
'msgtype':
|
||||
'm.text',
|
||||
|
|
@ -539,45 +550,42 @@ class Message extends StatelessWidget {
|
|||
originServerTs:
|
||||
DateTime.now(),
|
||||
);
|
||||
return Padding(
|
||||
padding:
|
||||
const EdgeInsets
|
||||
.only(
|
||||
left: 16,
|
||||
right: 16,
|
||||
top: 8,
|
||||
),
|
||||
child: Material(
|
||||
color: Colors
|
||||
.transparent,
|
||||
borderRadius:
|
||||
ReplyContent
|
||||
.borderRadius,
|
||||
child:
|
||||
InkWell(
|
||||
borderRadius:
|
||||
ReplyContent
|
||||
.borderRadius,
|
||||
onTap: () =>
|
||||
scrollToEventId(
|
||||
replyEvent
|
||||
.eventId,
|
||||
),
|
||||
child:
|
||||
AbsorbPointer(
|
||||
child:
|
||||
ReplyContent(
|
||||
replyEvent,
|
||||
ownMessage:
|
||||
ownMessage,
|
||||
timeline:
|
||||
timeline,
|
||||
return Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(
|
||||
left:
|
||||
16,
|
||||
right:
|
||||
16,
|
||||
top:
|
||||
8,
|
||||
),
|
||||
child: Material(
|
||||
color: Colors
|
||||
.transparent,
|
||||
borderRadius:
|
||||
ReplyContent
|
||||
.borderRadius,
|
||||
child: InkWell(
|
||||
borderRadius:
|
||||
ReplyContent.borderRadius,
|
||||
onTap: () => scrollToEventId(
|
||||
replyEvent
|
||||
.eventId,
|
||||
),
|
||||
child: AbsorbPointer(
|
||||
child: ReplyContent(
|
||||
replyEvent,
|
||||
ownMessage:
|
||||
ownMessage,
|
||||
timeline:
|
||||
timeline,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
MessageContent(
|
||||
displayEvent,
|
||||
|
|
@ -591,18 +599,17 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
if (event
|
||||
.hasAggregatedEvents(
|
||||
timeline,
|
||||
RelationshipTypes
|
||||
.edit,
|
||||
))
|
||||
timeline,
|
||||
RelationshipTypes
|
||||
.edit,
|
||||
))
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets
|
||||
.only(
|
||||
bottom: 8.0,
|
||||
left: 16.0,
|
||||
right: 16.0,
|
||||
),
|
||||
const EdgeInsets.only(
|
||||
bottom: 8.0,
|
||||
left: 16.0,
|
||||
right: 16.0,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize
|
||||
|
|
@ -614,22 +621,21 @@ class Message extends StatelessWidget {
|
|||
.edit_outlined,
|
||||
color: textColor
|
||||
.withAlpha(
|
||||
164,
|
||||
),
|
||||
164,
|
||||
),
|
||||
size: 14,
|
||||
),
|
||||
Text(
|
||||
displayEvent
|
||||
.originServerTs
|
||||
.localizedTimeShort(
|
||||
context,
|
||||
),
|
||||
style:
|
||||
TextStyle(
|
||||
context,
|
||||
),
|
||||
style: TextStyle(
|
||||
color: textColor
|
||||
.withAlpha(
|
||||
164,
|
||||
),
|
||||
164,
|
||||
),
|
||||
fontSize:
|
||||
11,
|
||||
),
|
||||
|
|
@ -657,46 +663,43 @@ class Message extends StatelessWidget {
|
|||
? Padding(
|
||||
padding:
|
||||
const EdgeInsets.all(
|
||||
4.0,
|
||||
),
|
||||
4.0,
|
||||
),
|
||||
child: Material(
|
||||
elevation: 4,
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
AppConfig.borderRadius,
|
||||
),
|
||||
AppConfig
|
||||
.borderRadius,
|
||||
),
|
||||
shadowColor: theme
|
||||
.colorScheme.surface
|
||||
.colorScheme
|
||||
.surface
|
||||
.withAlpha(128),
|
||||
child:
|
||||
SingleChildScrollView(
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection:
|
||||
Axis.horizontal,
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
...AppConfig
|
||||
.defaultReactions
|
||||
.map(
|
||||
(emoji) =>
|
||||
IconButton(
|
||||
...AppConfig.defaultReactions.map(
|
||||
(
|
||||
emoji,
|
||||
) => IconButton(
|
||||
padding:
|
||||
EdgeInsets
|
||||
.zero,
|
||||
icon: Center(
|
||||
child:
|
||||
Opacity(
|
||||
opacity: sentReactions
|
||||
.contains(
|
||||
emoji,
|
||||
)
|
||||
child: Opacity(
|
||||
opacity:
|
||||
sentReactions.contains(
|
||||
emoji,
|
||||
)
|
||||
? 0.33
|
||||
: 1,
|
||||
child: Text(
|
||||
emoji,
|
||||
style:
|
||||
const TextStyle(
|
||||
style: const TextStyle(
|
||||
fontSize:
|
||||
20,
|
||||
),
|
||||
|
|
@ -708,19 +711,20 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
onPressed:
|
||||
sentReactions
|
||||
.contains(
|
||||
emoji,
|
||||
)
|
||||
? null
|
||||
: () {
|
||||
onSelect(
|
||||
event,
|
||||
);
|
||||
event.room.sendReaction(
|
||||
event.eventId,
|
||||
emoji,
|
||||
);
|
||||
},
|
||||
.contains(
|
||||
emoji,
|
||||
)
|
||||
? null
|
||||
: () {
|
||||
onSelect(
|
||||
event,
|
||||
);
|
||||
event.room.sendReaction(
|
||||
event
|
||||
.eventId,
|
||||
emoji,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
|
|
@ -731,72 +735,55 @@ class Message extends StatelessWidget {
|
|||
tooltip: L10n.of(
|
||||
context,
|
||||
).customReaction,
|
||||
onPressed:
|
||||
() async {
|
||||
final emoji =
|
||||
await showAdaptiveBottomSheet<
|
||||
String>(
|
||||
onPressed: () async {
|
||||
final emoji = await showAdaptiveBottomSheet<String>(
|
||||
context:
|
||||
context,
|
||||
builder:
|
||||
(context) =>
|
||||
Scaffold(
|
||||
appBar:
|
||||
AppBar(
|
||||
title:
|
||||
Text(
|
||||
L10n.of(context)
|
||||
.customReaction,
|
||||
),
|
||||
leading:
|
||||
CloseButton(
|
||||
onPressed:
|
||||
() =>
|
||||
Navigator.of(
|
||||
builder: (context) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
L10n.of(
|
||||
context,
|
||||
).pop(
|
||||
null,
|
||||
),
|
||||
).customReaction,
|
||||
),
|
||||
leading: CloseButton(
|
||||
onPressed: () => Navigator.of(
|
||||
context,
|
||||
).pop(null),
|
||||
),
|
||||
),
|
||||
body:
|
||||
SizedBox(
|
||||
body: SizedBox(
|
||||
height: double
|
||||
.infinity,
|
||||
child:
|
||||
EmojiPicker(
|
||||
onEmojiSelected: (
|
||||
_,
|
||||
emoji,
|
||||
) =>
|
||||
Navigator.of(
|
||||
context,
|
||||
).pop(
|
||||
emoji
|
||||
.emoji,
|
||||
),
|
||||
config:
|
||||
Config(
|
||||
locale:
|
||||
Localizations.localeOf(context),
|
||||
emojiViewConfig:
|
||||
const EmojiViewConfig(
|
||||
child: EmojiPicker(
|
||||
onEmojiSelected:
|
||||
(
|
||||
_,
|
||||
emoji,
|
||||
) =>
|
||||
Navigator.of(
|
||||
context,
|
||||
).pop(
|
||||
emoji.emoji,
|
||||
),
|
||||
config: Config(
|
||||
locale: Localizations.localeOf(
|
||||
context,
|
||||
),
|
||||
emojiViewConfig: const EmojiViewConfig(
|
||||
backgroundColor:
|
||||
Colors.transparent,
|
||||
),
|
||||
bottomActionBarConfig:
|
||||
const BottomActionBarConfig(
|
||||
bottomActionBarConfig: const BottomActionBarConfig(
|
||||
enabled:
|
||||
false,
|
||||
),
|
||||
categoryViewConfig:
|
||||
CategoryViewConfig(
|
||||
categoryViewConfig: CategoryViewConfig(
|
||||
initCategory:
|
||||
Category.SMILEYS,
|
||||
backspaceColor:
|
||||
theme.colorScheme.primary,
|
||||
iconColor:
|
||||
theme.colorScheme.primary.withAlpha(
|
||||
iconColor: theme.colorScheme.primary.withAlpha(
|
||||
128,
|
||||
),
|
||||
iconColorSelected:
|
||||
|
|
@ -806,10 +793,8 @@ class Message extends StatelessWidget {
|
|||
backgroundColor:
|
||||
theme.colorScheme.surface,
|
||||
),
|
||||
skinToneConfig:
|
||||
SkinToneConfig(
|
||||
dialogBackgroundColor:
|
||||
Color.lerp(
|
||||
skinToneConfig: SkinToneConfig(
|
||||
dialogBackgroundColor: Color.lerp(
|
||||
theme.colorScheme.surface,
|
||||
theme.colorScheme.primaryContainer,
|
||||
0.75,
|
||||
|
|
@ -828,17 +813,18 @@ class Message extends StatelessWidget {
|
|||
}
|
||||
if (sentReactions
|
||||
.contains(
|
||||
emoji,
|
||||
)) {
|
||||
emoji,
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
onSelect(event);
|
||||
|
||||
await event.room
|
||||
.sendReaction(
|
||||
event.eventId,
|
||||
emoji,
|
||||
);
|
||||
event
|
||||
.eventId,
|
||||
emoji,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
|
|
@ -904,10 +890,7 @@ class Message extends StatelessWidget {
|
|||
onPressed: () => enterThread(event.eventId),
|
||||
icon: const Icon(Icons.message),
|
||||
label: Text(
|
||||
'${L10n.of(context).countReplies(threadChildren.length)} | ${threadChildren.first.calcLocalizedBodyFallback(
|
||||
MatrixLocals(L10n.of(context)),
|
||||
withSenderNamePrefix: true,
|
||||
)}',
|
||||
'${L10n.of(context).countReplies(threadChildren.length)} | ${threadChildren.first.calcLocalizedBodyFallback(MatrixLocals(L10n.of(context)), withSenderNamePrefix: true)}',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
|
|
@ -933,8 +916,9 @@ class Message extends StatelessWidget {
|
|||
vertical: 2,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(AppConfig.borderRadius / 3),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConfig.borderRadius / 3,
|
||||
),
|
||||
color: theme.colorScheme.surface.withAlpha(128),
|
||||
),
|
||||
child: Text(
|
||||
|
|
@ -1005,8 +989,10 @@ class BubblePainter extends CustomPainter {
|
|||
final scrollableRect = Offset.zero & scrollableBox.size;
|
||||
final bubbleBox = context.findRenderObject() as RenderBox;
|
||||
|
||||
final origin =
|
||||
bubbleBox.localToGlobal(Offset.zero, ancestor: scrollableBox);
|
||||
final origin = bubbleBox.localToGlobal(
|
||||
Offset.zero,
|
||||
ancestor: scrollableBox,
|
||||
);
|
||||
final paint = Paint()
|
||||
..shader = ui.Gradient.linear(
|
||||
scrollableRect.topCenter,
|
||||
|
|
|
|||
|
|
@ -50,9 +50,7 @@ class MessageContent extends StatelessWidget {
|
|||
if (event.content['can_request_session'] != true) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
event.calcLocalizedBodyFallback(MatrixLocals(l10n)),
|
||||
),
|
||||
content: Text(event.calcLocalizedBodyFallback(MatrixLocals(l10n))),
|
||||
),
|
||||
);
|
||||
return;
|
||||
|
|
@ -91,11 +89,7 @@ class MessageContent extends StatelessWidget {
|
|||
trailing: const Icon(Icons.lock_outlined),
|
||||
),
|
||||
const Divider(),
|
||||
Text(
|
||||
event.calcLocalizedBodyFallback(
|
||||
MatrixLocals(l10n),
|
||||
),
|
||||
),
|
||||
Text(event.calcLocalizedBodyFallback(MatrixLocals(l10n))),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -116,8 +110,9 @@ class MessageContent extends StatelessWidget {
|
|||
case MessageTypes.Image:
|
||||
case MessageTypes.Sticker:
|
||||
if (event.redacted) continue textmessage;
|
||||
final maxSize =
|
||||
event.messageType == MessageTypes.Sticker ? 128.0 : 256.0;
|
||||
final maxSize = event.messageType == MessageTypes.Sticker
|
||||
? 128.0
|
||||
: 256.0;
|
||||
final w = event.content
|
||||
.tryGetMap<String, Object?>('info')
|
||||
?.tryGet<int>('w');
|
||||
|
|
@ -152,12 +147,12 @@ class MessageContent extends StatelessWidget {
|
|||
return CuteContent(event);
|
||||
case MessageTypes.Audio:
|
||||
if (PlatformInfos.isMobile ||
|
||||
PlatformInfos.isMacOS ||
|
||||
PlatformInfos.isWeb
|
||||
// Disabled until https://github.com/bleonard252/just_audio_mpv/issues/3
|
||||
// is fixed
|
||||
// || PlatformInfos.isLinux
|
||||
) {
|
||||
PlatformInfos.isMacOS ||
|
||||
PlatformInfos.isWeb
|
||||
// Disabled until https://github.com/bleonard252/just_audio_mpv/issues/3
|
||||
// is fixed
|
||||
// || PlatformInfos.isLinux
|
||||
) {
|
||||
return AudioPlayerWidget(
|
||||
event,
|
||||
color: textColor,
|
||||
|
|
@ -193,8 +188,9 @@ class MessageContent extends StatelessWidget {
|
|||
fontSize: fontSize,
|
||||
);
|
||||
case MessageTypes.Location:
|
||||
final geoUri =
|
||||
Uri.tryParse(event.content.tryGet<String>('geo_uri')!);
|
||||
final geoUri = Uri.tryParse(
|
||||
event.content.tryGet<String>('geo_uri')!,
|
||||
);
|
||||
if (geoUri != null && geoUri.scheme == 'geo') {
|
||||
final latlong = geoUri.path
|
||||
.split(';')
|
||||
|
|
@ -206,7 +202,7 @@ class MessageContent extends StatelessWidget {
|
|||
latlong.first != null &&
|
||||
latlong.last != null) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
MapBubble(
|
||||
latitude: latlong.first!,
|
||||
|
|
@ -215,8 +211,10 @@ class MessageContent extends StatelessWidget {
|
|||
const SizedBox(height: 6),
|
||||
OutlinedButton.icon(
|
||||
icon: Icon(Icons.location_on_outlined, color: textColor),
|
||||
onPressed:
|
||||
UrlLauncher(context, geoUri.toString()).launchUrl,
|
||||
onPressed: UrlLauncher(
|
||||
context,
|
||||
geoUri.toString(),
|
||||
).launchUrl,
|
||||
label: Text(
|
||||
L10n.of(context).openInMaps,
|
||||
style: TextStyle(color: textColor),
|
||||
|
|
@ -248,25 +246,25 @@ class MessageContent extends StatelessWidget {
|
|||
html = '* $html';
|
||||
}
|
||||
|
||||
final bigEmotes = event.onlyEmotes &&
|
||||
final bigEmotes =
|
||||
event.onlyEmotes &&
|
||||
event.numberEmotes > 0 &&
|
||||
event.numberEmotes <= 3;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
child: HtmlMessage(
|
||||
html: html,
|
||||
textColor: textColor,
|
||||
room: event.room,
|
||||
fontSize: AppSettings.fontSizeFactor.value *
|
||||
fontSize:
|
||||
AppSettings.fontSizeFactor.value *
|
||||
AppConfig.messageFontSize *
|
||||
(bigEmotes ? 5 : 1),
|
||||
limitHeight: !selected,
|
||||
linkStyle: TextStyle(
|
||||
color: linkColor,
|
||||
fontSize: AppSettings.fontSizeFactor.value *
|
||||
fontSize:
|
||||
AppSettings.fontSizeFactor.value *
|
||||
AppConfig.messageFontSize,
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: linkColor,
|
||||
|
|
@ -352,16 +350,14 @@ class RedactionWidget extends StatelessWidget {
|
|||
future: event.redactedBecause?.fetchSenderUser(),
|
||||
builder: (context, snapshot) {
|
||||
final reason = event.redactedBecause?.content.tryGet<String>('reason');
|
||||
final redactedBy = snapshot.data?.calcDisplayname() ??
|
||||
final redactedBy =
|
||||
snapshot.data?.calcDisplayname() ??
|
||||
event.redactedBecause?.senderId.localpart ??
|
||||
L10n.of(context).user;
|
||||
return _ButtonContent(
|
||||
label: reason == null
|
||||
? L10n.of(context).redactedBy(redactedBy)
|
||||
: L10n.of(context).redactedByBecause(
|
||||
redactedBy,
|
||||
reason,
|
||||
),
|
||||
: L10n.of(context).redactedByBecause(redactedBy, reason),
|
||||
icon: '🗑️',
|
||||
textColor: buttonTextColor.withAlpha(128),
|
||||
onPressed: () => onInfoTab!(event),
|
||||
|
|
@ -390,18 +386,12 @@ class _ButtonContent extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
child: InkWell(
|
||||
onTap: onPressed,
|
||||
child: Text(
|
||||
'$icon $label',
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
fontSize: fontSize,
|
||||
),
|
||||
style: TextStyle(color: textColor, fontSize: fontSize),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -27,15 +27,15 @@ class MessageDownloadContent extends StatelessWidget {
|
|||
final filetype = (filename.contains('.')
|
||||
? filename.split('.').last.toUpperCase()
|
||||
: event.content
|
||||
.tryGetMap<String, dynamic>('info')
|
||||
?.tryGet<String>('mimetype')
|
||||
?.toUpperCase() ??
|
||||
'UNKNOWN');
|
||||
.tryGetMap<String, dynamic>('info')
|
||||
?.tryGet<String>('mimetype')
|
||||
?.toUpperCase() ??
|
||||
'UNKNOWN');
|
||||
final sizeString = event.sizeString ?? '?MB';
|
||||
final fileDescription = event.fileDescription;
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: .min,
|
||||
crossAxisAlignment: .start,
|
||||
spacing: 8,
|
||||
children: [
|
||||
Material(
|
||||
|
|
@ -47,7 +47,7 @@ class MessageDownloadContent extends StatelessWidget {
|
|||
width: 400,
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
spacing: 16,
|
||||
children: [
|
||||
CircleAvatar(
|
||||
|
|
@ -56,8 +56,8 @@ class MessageDownloadContent extends StatelessWidget {
|
|||
),
|
||||
Flexible(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: .start,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
Text(
|
||||
filename,
|
||||
|
|
@ -93,13 +93,15 @@ class MessageDownloadContent extends StatelessWidget {
|
|||
textScaleFactor: MediaQuery.textScalerOf(context).scale(1),
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
fontSize: AppSettings.fontSizeFactor.value *
|
||||
fontSize:
|
||||
AppSettings.fontSizeFactor.value *
|
||||
AppConfig.messageFontSize,
|
||||
),
|
||||
options: const LinkifyOptions(humanize: false),
|
||||
linkStyle: TextStyle(
|
||||
color: linkColor,
|
||||
fontSize: AppSettings.fontSizeFactor.value *
|
||||
fontSize:
|
||||
AppSettings.fontSizeFactor.value *
|
||||
AppConfig.messageFontSize,
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: linkColor,
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@ class MessageReactions extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final allReactionEvents =
|
||||
event.aggregatedEvents(timeline, RelationshipTypes.reaction);
|
||||
final allReactionEvents = event.aggregatedEvents(
|
||||
timeline,
|
||||
RelationshipTypes.reaction,
|
||||
);
|
||||
final reactionMap = <String, _ReactionEntry>{};
|
||||
final client = Matrix.of(context).client;
|
||||
|
||||
|
|
@ -113,7 +115,7 @@ class _Reaction extends StatelessWidget {
|
|||
Widget content;
|
||||
if (reactionKey.startsWith('mxc://')) {
|
||||
content = Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: <Widget>[
|
||||
MxcImage(
|
||||
uri: Uri.parse(reactionKey),
|
||||
|
|
@ -190,17 +192,14 @@ class _AdaptableReactorsDialog extends StatelessWidget {
|
|||
final Client? client;
|
||||
final _ReactionEntry? reactionEntry;
|
||||
|
||||
const _AdaptableReactorsDialog({
|
||||
this.client,
|
||||
this.reactionEntry,
|
||||
});
|
||||
const _AdaptableReactorsDialog({this.client, this.reactionEntry});
|
||||
|
||||
Future<bool?> show(BuildContext context) => showAdaptiveDialog(
|
||||
context: context,
|
||||
builder: (context) => this,
|
||||
barrierDismissible: true,
|
||||
useRootNavigator: false,
|
||||
);
|
||||
context: context,
|
||||
builder: (context) => this,
|
||||
barrierDismissible: true,
|
||||
useRootNavigator: false,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -226,9 +225,6 @@ class _AdaptableReactorsDialog extends StatelessWidget {
|
|||
|
||||
final title = Center(child: Text(reactionEntry!.key));
|
||||
|
||||
return AlertDialog.adaptive(
|
||||
title: title,
|
||||
content: body,
|
||||
);
|
||||
return AlertDialog.adaptive(title: title, content: body);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,10 +24,8 @@ class PollWidget extends StatelessWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
void _endPoll(BuildContext context) => showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => event.endPoll(),
|
||||
);
|
||||
void _endPoll(BuildContext context) =>
|
||||
showFutureLoadingDialog(context: context, future: () => event.endPoll());
|
||||
|
||||
void _toggleVote(
|
||||
BuildContext context,
|
||||
|
|
@ -60,20 +58,19 @@ class PollWidget extends StatelessWidget {
|
|||
}
|
||||
final responses = event.getPollResponses(timeline);
|
||||
final pollHasBeenEnded = event.getPollHasBeenEnded(timeline);
|
||||
final canVote = event.room.canSendEvent(PollEventContent.responseType) &&
|
||||
final canVote =
|
||||
event.room.canSendEvent(PollEventContent.responseType) &&
|
||||
!pollHasBeenEnded;
|
||||
final maxPolls = responses.length;
|
||||
final answersVisible =
|
||||
eventContent.pollStartContent.kind == PollKind.disclosed ||
|
||||
pollHasBeenEnded;
|
||||
pollHasBeenEnded;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: .min,
|
||||
crossAxisAlignment: .start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
|
|
@ -82,13 +79,15 @@ class PollWidget extends StatelessWidget {
|
|||
textScaleFactor: MediaQuery.textScalerOf(context).scale(1),
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
fontSize: AppSettings.fontSizeFactor.value *
|
||||
fontSize:
|
||||
AppSettings.fontSizeFactor.value *
|
||||
AppConfig.messageFontSize,
|
||||
),
|
||||
options: const LinkifyOptions(humanize: false),
|
||||
linkStyle: TextStyle(
|
||||
color: linkColor,
|
||||
fontSize: AppSettings.fontSizeFactor.value *
|
||||
fontSize:
|
||||
AppSettings.fontSizeFactor.value *
|
||||
AppConfig.messageFontSize,
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: linkColor,
|
||||
|
|
@ -97,99 +96,101 @@ class PollWidget extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
Divider(color: linkColor.withAlpha(64)),
|
||||
...eventContent.pollStartContent.answers.map(
|
||||
(answer) {
|
||||
final votedUserIds = responses.entries
|
||||
.where((entry) => entry.value.contains(answer.id))
|
||||
.map((entry) => entry.key)
|
||||
.toSet();
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: CheckboxListTile.adaptive(
|
||||
value: responses[event.room.client.userID!]
|
||||
?.contains(answer.id) ??
|
||||
false,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
checkboxScaleFactor: 1.5,
|
||||
checkboxShape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(32),
|
||||
...eventContent.pollStartContent.answers.map((answer) {
|
||||
final votedUserIds = responses.entries
|
||||
.where((entry) => entry.value.contains(answer.id))
|
||||
.map((entry) => entry.key)
|
||||
.toSet();
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: CheckboxListTile.adaptive(
|
||||
value:
|
||||
responses[event.room.client.userID!]?.contains(answer.id) ??
|
||||
false,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
checkboxScaleFactor: 1.5,
|
||||
checkboxShape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(32),
|
||||
),
|
||||
onChanged: !canVote
|
||||
? null
|
||||
: (_) => _toggleVote(
|
||||
context,
|
||||
answer.id,
|
||||
eventContent.pollStartContent.maxSelections,
|
||||
),
|
||||
title: Text(
|
||||
answer.mText,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
fontSize:
|
||||
AppConfig.messageFontSize *
|
||||
AppSettings.fontSizeFactor.value,
|
||||
),
|
||||
onChanged: !canVote
|
||||
? null
|
||||
: (_) => _toggleVote(
|
||||
context,
|
||||
answer.id,
|
||||
eventContent.pollStartContent.maxSelections,
|
||||
),
|
||||
title: Text(
|
||||
answer.mText,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
fontSize: AppConfig.messageFontSize *
|
||||
AppSettings.fontSizeFactor.value,
|
||||
),
|
||||
),
|
||||
subtitle: answersVisible
|
||||
? Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
L10n.of(context)
|
||||
.countVotes(votedUserIds.length),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: linkColor,
|
||||
fontSize:
|
||||
),
|
||||
subtitle: answersVisible
|
||||
? Column(
|
||||
crossAxisAlignment: .start,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
L10n.of(
|
||||
context,
|
||||
).countVotes(votedUserIds.length),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: linkColor,
|
||||
fontSize:
|
||||
12 * AppSettings.fontSizeFactor.value,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
...votedUserIds.map((userId) {
|
||||
final user = event.room
|
||||
.getState(EventTypes.RoomMember, userId)
|
||||
?.asUser(event.room);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 2.0,
|
||||
),
|
||||
child: Avatar(
|
||||
mxContent: user?.avatarUrl,
|
||||
name:
|
||||
user?.calcDisplayname() ??
|
||||
userId.localpart,
|
||||
size:
|
||||
12 * AppSettings.fontSizeFactor.value,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
...votedUserIds.map((userId) {
|
||||
final user = event.room
|
||||
.getState(EventTypes.RoomMember, userId)
|
||||
?.asUser(event.room);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 2.0,
|
||||
),
|
||||
child: Avatar(
|
||||
mxContent: user?.avatarUrl,
|
||||
name: user?.calcDisplayname() ??
|
||||
userId.localpart,
|
||||
size: 12 *
|
||||
AppSettings.fontSizeFactor.value,
|
||||
),
|
||||
);
|
||||
}),
|
||||
const SizedBox(width: 2),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
const SizedBox(width: 2),
|
||||
],
|
||||
),
|
||||
LinearProgressIndicator(
|
||||
color: linkColor,
|
||||
backgroundColor: linkColor.withAlpha(128),
|
||||
borderRadius:
|
||||
BorderRadius.circular(AppConfig.borderRadius),
|
||||
value: maxPolls == 0
|
||||
? 0
|
||||
: votedUserIds.length / maxPolls,
|
||||
),
|
||||
LinearProgressIndicator(
|
||||
color: linkColor,
|
||||
backgroundColor: linkColor.withAlpha(128),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConfig.borderRadius,
|
||||
),
|
||||
],
|
||||
)
|
||||
: null,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
value: maxPolls == 0
|
||||
? 0
|
||||
: votedUserIds.length / maxPolls,
|
||||
),
|
||||
],
|
||||
)
|
||||
: null,
|
||||
),
|
||||
);
|
||||
}),
|
||||
if (!pollHasBeenEnded && event.senderId == event.room.client.userID)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
|
|
|
|||
|
|
@ -29,21 +29,22 @@ class ReplyContent extends StatelessWidget {
|
|||
final theme = Theme.of(context);
|
||||
|
||||
final timeline = this.timeline;
|
||||
final displayEvent =
|
||||
timeline != null ? replyEvent.getDisplayEvent(timeline) : replyEvent;
|
||||
final displayEvent = timeline != null
|
||||
? replyEvent.getDisplayEvent(timeline)
|
||||
: replyEvent;
|
||||
final fontSize =
|
||||
AppConfig.messageFontSize * AppSettings.fontSizeFactor.value;
|
||||
final color = theme.brightness == Brightness.dark
|
||||
? theme.colorScheme.onTertiaryContainer
|
||||
: ownMessage
|
||||
? theme.colorScheme.tertiaryContainer
|
||||
: theme.colorScheme.tertiary;
|
||||
? theme.colorScheme.tertiaryContainer
|
||||
: theme.colorScheme.tertiary;
|
||||
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
borderRadius: borderRadius,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: 5,
|
||||
|
|
@ -56,8 +57,8 @@ class ReplyContent extends StatelessWidget {
|
|||
const SizedBox(width: 6),
|
||||
Flexible(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: .start,
|
||||
mainAxisAlignment: .center,
|
||||
children: <Widget>[
|
||||
FutureBuilder<User?>(
|
||||
initialData: displayEvent.senderFromMemoryOrFallback,
|
||||
|
|
@ -87,8 +88,8 @@ class ReplyContent extends StatelessWidget {
|
|||
color: theme.brightness == Brightness.dark
|
||||
? theme.colorScheme.onSurface
|
||||
: ownMessage
|
||||
? theme.colorScheme.onTertiary
|
||||
: theme.colorScheme.onSurface,
|
||||
? theme.colorScheme.onTertiary
|
||||
: theme.colorScheme.onSurface,
|
||||
fontSize: fontSize,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class RoomCreationStateEvent extends StatelessWidget {
|
|||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
Avatar(
|
||||
mxContent: event.room.avatar,
|
||||
|
|
|
|||
|
|
@ -35,8 +35,9 @@ class StateMessage extends StatelessWidget {
|
|||
padding: const EdgeInsets.all(4),
|
||||
child: Material(
|
||||
color: theme.colorScheme.surface.withAlpha(128),
|
||||
borderRadius:
|
||||
BorderRadius.circular(AppConfig.borderRadius / 3),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConfig.borderRadius / 3,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
|
|
|
|||
|
|
@ -35,8 +35,10 @@ class EventVideoPlayer extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
final supportsVideoPlayer = PlatformInfos.supportsVideoPlayer;
|
||||
|
||||
final blurHash = (event.infoMap as Map<String, dynamic>)
|
||||
.tryGet<String>('xyz.amorgan.blurhash') ??
|
||||
final blurHash =
|
||||
(event.infoMap as Map<String, dynamic>).tryGet<String>(
|
||||
'xyz.amorgan.blurhash',
|
||||
) ??
|
||||
fallbackBlurHash;
|
||||
final fileDescription = event.fileDescription;
|
||||
const maxDimension = 300.0;
|
||||
|
|
@ -49,11 +51,12 @@ class EventVideoPlayer extends StatelessWidget {
|
|||
final height = videoHeight / modifier;
|
||||
|
||||
final durationInt = infoMap?.tryGet<int>('duration');
|
||||
final duration =
|
||||
durationInt == null ? null : Duration(milliseconds: durationInt);
|
||||
final duration = durationInt == null
|
||||
? null
|
||||
: Duration(milliseconds: durationInt);
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisSize: .min,
|
||||
spacing: 8,
|
||||
children: [
|
||||
Material(
|
||||
|
|
@ -128,22 +131,21 @@ class EventVideoPlayer extends StatelessWidget {
|
|||
SizedBox(
|
||||
width: width,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
child: Linkify(
|
||||
text: fileDescription,
|
||||
textScaleFactor: MediaQuery.textScalerOf(context).scale(1),
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
fontSize: AppSettings.fontSizeFactor.value *
|
||||
fontSize:
|
||||
AppSettings.fontSizeFactor.value *
|
||||
AppConfig.messageFontSize,
|
||||
),
|
||||
options: const LinkifyOptions(humanize: false),
|
||||
linkStyle: TextStyle(
|
||||
color: linkColor,
|
||||
fontSize: AppSettings.fontSizeFactor.value *
|
||||
fontSize:
|
||||
AppSettings.fontSizeFactor.value *
|
||||
AppConfig.messageFontSize,
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: linkColor,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue