fix: salas removidas de vez, paginação no mural, mídia em largura total e teclado nos comentários

This commit is contained in:
2026-09-14 17:15:52 -03:00
parent 8927e80cce
commit 9d69e833bd
8 changed files with 234 additions and 134 deletions

View File

@@ -668,6 +668,7 @@ class Message extends StatelessWidget {
timeline: timeline,
selected: selected,
bigEmojis: bigEmojis,
fullWidthCard: card,
),
],
),

View File

@@ -33,6 +33,7 @@ class MessageContent extends StatelessWidget {
final Timeline timeline;
final bool selected;
final Set<String> bigEmojis;
final bool fullWidthCard;
const MessageContent(
this.event, {
@@ -44,6 +45,7 @@ class MessageContent extends StatelessWidget {
required this.borderRadius,
required this.selected,
required this.bigEmojis,
this.fullWidthCard = false,
});
@override
@@ -67,13 +69,40 @@ class MessageContent extends StatelessWidget {
final h = event.content
.tryGetMap<String, Object?>('info')
?.tryGet<int>('h');
var width = maxSize;
var width = fullWidthCard && event.messageType == MessageTypes.Image
? double.infinity
: maxSize;
var height = maxSize;
var fit = event.messageType == MessageTypes.Sticker
? BoxFit.contain
: BoxFit.cover;
if (w != null && h != null) {
fit = BoxFit.contain;
if (fullWidthCard &&
event.messageType == MessageTypes.Image &&
w > 0 &&
h > 0) {
return AspectRatio(
aspectRatio: w / h,
child: ImageBubble(
event,
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
borderRadius: borderRadius,
timeline: timeline,
textColor: textColor,
onTap: () => showDialog(
context: context,
builder: (_) => ImageViewer(
event,
timeline: timeline,
outerContext: context,
),
),
),
);
}
if (w > h) {
width = maxSize;
height = max(32, maxSize * (h / w));
@@ -124,6 +153,7 @@ class MessageContent extends StatelessWidget {
textColor: textColor,
linkColor: linkColor,
timeline: timeline,
expand: fullWidthCard,
);
case MessageTypes.File:
return MessageDownloadContent(

View File

@@ -24,12 +24,14 @@ class EventVideoPlayer extends StatelessWidget {
final Timeline? timeline;
final Color? textColor;
final Color? linkColor;
final bool expand;
const EventVideoPlayer(
this.event, {
this.timeline,
this.textColor,
this.linkColor,
this.expand = false,
super.key,
});
@@ -49,16 +51,74 @@ class EventVideoPlayer extends StatelessWidget {
final infoMap = event.content.tryGetMap<String, Object?>('info');
final videoWidth = infoMap?.tryGet<int>('w') ?? maxDimension;
final videoHeight = infoMap?.tryGet<int>('h') ?? maxDimension;
final hasDimensions = videoWidth > 0 && videoHeight > 0;
final modifier = max(videoWidth, videoHeight) / maxDimension;
final width = videoWidth / modifier;
final height = videoHeight / modifier;
final width = expand ? double.infinity : videoWidth / modifier;
final height = expand
? (hasDimensions ? double.infinity : maxDimension)
: videoHeight / modifier;
final durationInt = infoMap?.tryGet<int>('duration');
final duration = durationInt == null
? null
: Duration(milliseconds: durationInt);
final player = SizedBox(
width: width,
height: height,
child: Hero(
tag: event.eventId,
child: Stack(
children: [
if (event.hasThumbnail &&
AppSettings.showThumbnailsInTimeline.value)
MxcImage(
event: event,
cacheKey: event.transactionId ?? event.eventId,
cacheName: event.room.id,
isThumbnail: true,
width: width,
height: height,
fit: BoxFit.cover,
placeholder: (context) => BlurHash(
blurhash: blurHash,
width: width,
height: height,
fit: BoxFit.cover,
),
)
else
BlurHash(
blurhash: blurHash,
width: width,
height: height,
fit: BoxFit.cover,
),
Center(
child: CircleAvatar(
child: supportsVideoPlayer
? const Icon(Icons.play_arrow_outlined)
: const Icon(Icons.file_download_outlined),
),
),
if (duration != null)
Positioned(
bottom: 8,
left: 16,
child: Text(
'${duration.inMinutes.toString().padLeft(2, '0')}:${(duration.inSeconds % 60).toString().padLeft(2, '0')}',
style: TextStyle(
color: Colors.white,
backgroundColor: Colors.black.withAlpha(32),
),
),
),
],
),
),
);
return Column(
mainAxisSize: .min,
spacing: 8,
@@ -78,60 +138,12 @@ class EventVideoPlayer extends StatelessWidget {
)
: event.saveFile(context),
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
child: SizedBox(
width: width,
height: height,
child: Hero(
tag: event.eventId,
child: Stack(
children: [
if (event.hasThumbnail &&
AppSettings.showThumbnailsInTimeline.value)
MxcImage(
event: event,
cacheKey: event.transactionId ?? event.eventId,
cacheName: event.room.id,
isThumbnail: true,
width: width,
height: height,
fit: BoxFit.cover,
placeholder: (context) => BlurHash(
blurhash: blurHash,
width: width,
height: height,
fit: BoxFit.cover,
),
)
else
BlurHash(
blurhash: blurHash,
width: width,
height: height,
fit: BoxFit.cover,
),
Center(
child: CircleAvatar(
child: supportsVideoPlayer
? const Icon(Icons.play_arrow_outlined)
: const Icon(Icons.file_download_outlined),
),
),
if (duration != null)
Positioned(
bottom: 8,
left: 16,
child: Text(
'${duration.inMinutes.toString().padLeft(2, '0')}:${(duration.inSeconds % 60).toString().padLeft(2, '0')}',
style: TextStyle(
color: Colors.white,
backgroundColor: Colors.black.withAlpha(32),
),
),
),
],
),
),
),
child: expand && hasDimensions
? AspectRatio(
aspectRatio: videoWidth / videoHeight,
child: player,
)
: player,
),
),
if (fileDescription != null && textColor != null && linkColor != null)