Revert "Добавил кастомизацию+, убрал жесты потому что они мне жизнь сломали"

This reverts commit 9ca9f0c2d4.
This commit is contained in:
jganenok
2025-12-05 18:42:00 +07:00
parent 9ca9f0c2d4
commit e5beed10d9
7 changed files with 261 additions and 1235 deletions

View File

@@ -657,7 +657,9 @@ class ChatMessageBubble extends StatelessWidget {
Uint8List? lowQualityBytes,
int? videoType,
}) {
// Логика открытия плеера
void openFullScreenVideo() async {
// Показываем индикатор загрузки, пока получаем URL
showDialog(
context: context,
barrierDismissible: false,
@@ -667,12 +669,12 @@ class ChatMessageBubble extends StatelessWidget {
try {
final videoUrl = await ApiService.instance.getVideoUrl(
videoId,
chatId!,
chatId!, // chatId из `build`
messageId,
);
if (!context.mounted) return;
Navigator.pop(context);
if (!context.mounted) return; // [!code ++] Проверка правильным способом
Navigator.pop(context); // Убираем индикатор
Navigator.push(
context,
MaterialPageRoute(
@@ -680,8 +682,8 @@ class ChatMessageBubble extends StatelessWidget {
),
);
} catch (e) {
if (!context.mounted) return;
Navigator.pop(context);
if (!context.mounted) return; // [!code ++] Проверка правильным способом
Navigator.pop(context); // Убираем индикатор
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Не удалось загрузить видео: $e'),
@@ -703,58 +705,55 @@ class ChatMessageBubble extends StatelessWidget {
);
}
return RepaintBoundary(
key: ValueKey('video_preview_boundary_${messageId}_$videoId'),
child: GestureDetector(
onTap: openFullScreenVideo,
child: AspectRatio(
aspectRatio: 16 / 9,
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Stack(
alignment: Alignment.center,
fit: StackFit.expand,
children: [
(highQualityUrl != null && highQualityUrl.isNotEmpty) ||
(lowQualityBytes != null)
? _ProgressiveNetworkImage(
key: ValueKey('video_preview_image_${messageId}_$videoId'),
url: highQualityUrl ?? '',
previewBytes: lowQualityBytes,
width: 220,
height: 160,
fit: BoxFit.cover,
keepAlive: true,
)
: Container(
color: Colors.black26,
child: const Center(
child: Icon(
Icons.video_library_outlined,
color: Colors.white,
size: 40,
),
return GestureDetector(
onTap: openFullScreenVideo,
child: AspectRatio(
aspectRatio: 16 / 9,
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Stack(
alignment: Alignment.center,
fit: StackFit.expand,
children: [
// Если у нас есть ХОТЬ ЧТО-ТО (блюр или URL), показываем ProgressiveImage
(highQualityUrl != null && highQualityUrl.isNotEmpty) ||
(lowQualityBytes != null)
? _ProgressiveNetworkImage(
url: highQualityUrl ?? '',
previewBytes: lowQualityBytes,
width: 220,
height: 160,
fit: BoxFit.cover,
keepAlive: false,
)
: Container(
color: Colors.black26,
child: const Center(
child: Icon(
Icons.video_library_outlined,
color: Colors.white,
size: 40,
),
),
Container(
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.15),
),
child: Icon(
Icons.play_circle_filled_outlined,
color: Colors.white.withOpacity(0.95),
size: 50,
shadows: const [
Shadow(
color: Colors.black38,
blurRadius: 4,
offset: Offset(0, 2),
),
],
),
),
Container(
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.15),
),
],
),
child: Icon(
Icons.play_circle_filled_outlined,
color: Colors.white.withOpacity(0.95),
size: 50,
shadows: const [
Shadow(
color: Colors.black38,
blurRadius: 4,
offset: Offset(0, 2),
),
],
),
),
],
),
),
),
@@ -2005,16 +2004,13 @@ class ChatMessageBubble extends StatelessWidget {
padding: const EdgeInsets.only(bottom: 4.0),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 300),
child: RepaintBoundary(
key: ValueKey('video_preview_${message.id}_$videoId'),
child: _buildVideoPreview(
context: context,
videoId: videoId,
messageId: message.id,
highQualityUrl: highQualityThumbnailUrl,
lowQualityBytes: previewBytes,
videoType: videoType,
),
child: _buildVideoPreview(
context: context,
videoId: videoId,
messageId: message.id,
highQualityUrl: highQualityThumbnailUrl,
lowQualityBytes: previewBytes,
videoType: videoType,
),
),
),
@@ -2183,16 +2179,13 @@ class ChatMessageBubble extends StatelessWidget {
widgets.add(
Padding(
padding: const EdgeInsets.only(bottom: 4.0),
child: RepaintBoundary(
key: ValueKey('video_preview_${message.id}_$videoId'),
child: _buildVideoPreview(
context: context,
videoId: videoId,
messageId: message.id,
highQualityUrl: highQualityThumbnailUrl,
lowQualityBytes: previewBytes,
videoType: videoType,
),
child: _buildVideoPreview(
context: context,
videoId: videoId,
messageId: message.id,
highQualityUrl: highQualityThumbnailUrl,
lowQualityBytes: previewBytes,
videoType: videoType,
),
),
);

View File

@@ -2,7 +2,6 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:gwid/models/chat.dart';
import 'package:gwid/models/contact.dart';
import 'package:gwid/services/avatar_cache_service.dart';
class GroupAvatars extends StatelessWidget {
final Chat chat;
@@ -40,13 +39,13 @@ class GroupAvatars extends StatelessWidget {
double adaptiveAvatarSize;
if (totalParticipants <= 2) {
adaptiveAvatarSize =
avatarSize * 1.5;
avatarSize * 1.5; // Большие аватары для 1-2 участников
} else if (totalParticipants <= 4) {
adaptiveAvatarSize =
avatarSize * 1.2;
avatarSize * 1.2; // Средние аватары для 3-4 участников
} else {
adaptiveAvatarSize =
avatarSize * 0.8;
avatarSize * 0.8; // Маленькие аватары для 5+ участников
}
return SizedBox(
@@ -115,91 +114,45 @@ class GroupAvatars extends StatelessWidget {
) {
final colors = Theme.of(context).colorScheme;
if (contact == null || contact.photoBaseUrl == null || contact.photoBaseUrl!.isEmpty) {
return Container(
width: size,
height: size,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: colors.surface, width: 2),
boxShadow: [
BoxShadow(
color: colors.shadow.withOpacity(0.3),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: CircleAvatar(
radius: size / 2,
backgroundColor: contact != null
? colors.primaryContainer
: colors.secondaryContainer,
child: Text(
contact?.name.isNotEmpty == true
? contact!.name[0].toUpperCase()
: participantId.toString().substring(
participantId.toString().length - 1,
),
style: TextStyle(
color: contact != null
? colors.onPrimaryContainer
: colors.onSecondaryContainer,
fontSize: size * 0.5,
fontWeight: FontWeight.w600,
),
return Container(
width: size,
height: size,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: colors.surface, width: 2),
boxShadow: [
BoxShadow(
color: colors.shadow.withOpacity(0.3),
blurRadius: 4,
offset: const Offset(0, 2),
),
),
);
}
return FutureBuilder<ImageProvider?>(
future: AvatarCacheService().getAvatar(contact.photoBaseUrl, userId: participantId),
builder: (context, snapshot) {
ImageProvider? imageProvider;
if (snapshot.hasData && snapshot.data != null) {
imageProvider = snapshot.data;
} else {
imageProvider = NetworkImage(contact.photoBaseUrl!);
}
return Container(
width: size,
height: size,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: colors.surface, width: 2),
boxShadow: [
BoxShadow(
color: colors.shadow.withOpacity(0.3),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: CircleAvatar(
radius: size / 2,
backgroundColor: colors.primaryContainer,
backgroundImage: imageProvider,
onBackgroundImageError: (exception, stackTrace) {
},
child: imageProvider == null
? Text(
contact.name.isNotEmpty
? contact.name[0].toUpperCase()
: participantId.toString().substring(
participantId.toString().length - 1,
),
style: TextStyle(
color: colors.onPrimaryContainer,
fontSize: size * 0.5,
fontWeight: FontWeight.w600,
),
)
: null,
),
);
},
],
),
child: CircleAvatar(
radius: size / 2,
backgroundColor: contact != null
? colors.primaryContainer
: colors.secondaryContainer,
backgroundImage: contact?.photoBaseUrl != null
? NetworkImage(contact!.photoBaseUrl!)
: null,
child: contact?.photoBaseUrl == null
? Text(
contact?.name.isNotEmpty == true
? contact!.name[0].toUpperCase()
: participantId.toString().substring(
participantId.toString().length - 1,
), // Последняя цифра ID
style: TextStyle(
color: contact != null
? colors.onPrimaryContainer
: colors.onSecondaryContainer,
fontSize: size * 0.5,
fontWeight: FontWeight.w600,
),
)
: null,
),
);
}