Sync update: 2026-05-18 21:13:35
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -152,11 +153,13 @@ class MessageBubble extends StatelessWidget {
|
||||
Widget _buildAckIcon(int ack) {
|
||||
switch (ack) {
|
||||
case 1: // Pending/Queued
|
||||
return const Icon(Icons.access_time, size: 13, color: AppTheme.textSecondary);
|
||||
return const Icon(Icons.access_time,
|
||||
size: 13, color: AppTheme.textSecondary);
|
||||
case 2: // Sent (single grey tick)
|
||||
return const Icon(Icons.done, size: 15, color: AppTheme.textSecondary);
|
||||
case 3: // Delivered (double grey tick)
|
||||
return const Icon(Icons.done_all, size: 15, color: AppTheme.textSecondary);
|
||||
return const Icon(Icons.done_all,
|
||||
size: 15, color: AppTheme.textSecondary);
|
||||
case 4: // Read (double blue tick)
|
||||
return const Icon(Icons.done_all, size: 15, color: Colors.blue);
|
||||
case 5: // Played audio/video (double blue with wave icon)
|
||||
@@ -250,7 +253,8 @@ class _InteractiveMediaWidgetState extends State<InteractiveMediaWidget> {
|
||||
await _player.pause();
|
||||
} else {
|
||||
final bytes = base64Decode(base64Data);
|
||||
final safeId = widget.message.id.replaceAll(RegExp(r'[^a-zA-Z0-9]'), '');
|
||||
final safeId =
|
||||
widget.message.id.replaceAll(RegExp(r'[^a-zA-Z0-9]'), '');
|
||||
final tempDir = Directory.systemTemp;
|
||||
final tempFile = File('${tempDir.path}/voice_$safeId.mp3');
|
||||
|
||||
@@ -293,7 +297,8 @@ class _InteractiveMediaWidgetState extends State<InteractiveMediaWidget> {
|
||||
child: const SizedBox(
|
||||
width: 24,
|
||||
height: 24,
|
||||
child: CircularProgressIndicator(strokeWidth: 2, color: AppTheme.primary),
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2, color: AppTheme.primary),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -318,12 +323,16 @@ class _InteractiveMediaWidgetState extends State<InteractiveMediaWidget> {
|
||||
children: [
|
||||
Text(
|
||||
_getLabel(),
|
||||
style: const TextStyle(color: AppTheme.textPrimary, fontWeight: FontWeight.w500, fontSize: 13),
|
||||
style: const TextStyle(
|
||||
color: AppTheme.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 13),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
const Text(
|
||||
'Tap to download',
|
||||
style: TextStyle(color: AppTheme.textSecondary, fontSize: 10),
|
||||
style:
|
||||
TextStyle(color: AppTheme.textSecondary, fontSize: 10),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -397,7 +406,9 @@ class _InteractiveMediaWidgetState extends State<InteractiveMediaWidget> {
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
_isPlaying ? Icons.pause_circle_filled : Icons.play_circle_filled,
|
||||
_isPlaying
|
||||
? Icons.pause_circle_filled
|
||||
: Icons.play_circle_filled,
|
||||
color: AppTheme.primary,
|
||||
size: 36,
|
||||
),
|
||||
@@ -413,8 +424,10 @@ class _InteractiveMediaWidgetState extends State<InteractiveMediaWidget> {
|
||||
SliderTheme(
|
||||
data: SliderTheme.of(context).copyWith(
|
||||
trackHeight: 2.5,
|
||||
thumbShape: const RoundSliderThumbShape(enabledThumbRadius: 5),
|
||||
overlayShape: const RoundSliderOverlayShape(overlayRadius: 10),
|
||||
thumbShape:
|
||||
const RoundSliderThumbShape(enabledThumbRadius: 5),
|
||||
overlayShape:
|
||||
const RoundSliderOverlayShape(overlayRadius: 10),
|
||||
activeTrackColor: AppTheme.primary,
|
||||
inactiveTrackColor: AppTheme.surfaceLight,
|
||||
thumbColor: AppTheme.primary,
|
||||
@@ -423,7 +436,8 @@ class _InteractiveMediaWidgetState extends State<InteractiveMediaWidget> {
|
||||
child: Slider(
|
||||
value: _audioProgress.clamp(0.0, 1.0),
|
||||
onChanged: (v) async {
|
||||
final targetMs = (v * _audioDurationSeconds * 1000).toInt();
|
||||
final targetMs =
|
||||
(v * _audioDurationSeconds * 1000).toInt();
|
||||
await _player.seek(Duration(milliseconds: targetMs));
|
||||
},
|
||||
),
|
||||
@@ -457,11 +471,13 @@ class _InteractiveMediaWidgetState extends State<InteractiveMediaWidget> {
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.check_circle_outline, color: AppTheme.primary, size: 32),
|
||||
const Icon(Icons.check_circle_outline,
|
||||
color: AppTheme.primary, size: 32),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
_getLabel(),
|
||||
style: const TextStyle(color: AppTheme.textPrimary, fontWeight: FontWeight.w500),
|
||||
style: const TextStyle(
|
||||
color: AppTheme.textPrimary, fontWeight: FontWeight.w500),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -470,21 +486,31 @@ class _InteractiveMediaWidgetState extends State<InteractiveMediaWidget> {
|
||||
|
||||
IconData _getIcon() {
|
||||
switch (widget.message.type) {
|
||||
case "image": return Icons.photo_outlined;
|
||||
case "video": return Icons.videocam_outlined;
|
||||
case "audio": return Icons.audiotrack_outlined;
|
||||
case "sticker": return Icons.emoji_emotions_outlined;
|
||||
default: return Icons.insert_drive_file_outlined;
|
||||
case "image":
|
||||
return Icons.photo_outlined;
|
||||
case "video":
|
||||
return Icons.videocam_outlined;
|
||||
case "audio":
|
||||
return Icons.audiotrack_outlined;
|
||||
case "sticker":
|
||||
return Icons.emoji_emotions_outlined;
|
||||
default:
|
||||
return Icons.insert_drive_file_outlined;
|
||||
}
|
||||
}
|
||||
|
||||
String _getLabel() {
|
||||
switch (widget.message.type) {
|
||||
case "image": return "Image Attachment";
|
||||
case "video": return "Video Attachment";
|
||||
case "audio": return "Audio / Voice Note";
|
||||
case "sticker": return "Sticker Attachment";
|
||||
default: return "File Attachment";
|
||||
case "image":
|
||||
return "Image Attachment";
|
||||
case "video":
|
||||
return "Video Attachment";
|
||||
case "audio":
|
||||
return "Audio / Voice Note";
|
||||
case "sticker":
|
||||
return "Sticker Attachment";
|
||||
default:
|
||||
return "File Attachment";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user