feat: Enable direct chat initiation from agent network, improve GIF rendering in chat, and fix message order and webview authentication.
This commit is contained in:
@@ -186,6 +186,11 @@ class _ChatScreenState extends ConsumerState<ChatScreen> {
|
||||
return trimmed.contains('giphy.com/') || trimmed.contains('giphy.gif');
|
||||
}
|
||||
|
||||
bool _isGifUrl(String url) {
|
||||
final lower = url.trim().toLowerCase();
|
||||
return lower.endsWith('.gif') || _isGiphyUrl(url) || lower.contains('tenor.com/');
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// BUILD
|
||||
// ============================================================
|
||||
@@ -735,6 +740,7 @@ class _ChatScreenState extends ConsumerState<ChatScreen> {
|
||||
|
||||
// GIF from Giphy (direct URL) or S3 image
|
||||
final isDirectUrl = imageUrl.startsWith('http://') || imageUrl.startsWith('https://');
|
||||
final isGif = _isGifUrl(imageUrl) || message.mimeType == 'image/gif';
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => _showImageFullScreen(context, imageUrl),
|
||||
@@ -745,19 +751,30 @@ class _ChatScreenState extends ConsumerState<ChatScreen> {
|
||||
maxWidth: 250,
|
||||
maxHeight: 250,
|
||||
),
|
||||
child: isDirectUrl
|
||||
? CachedNetworkImage(
|
||||
imageUrl: imageUrl,
|
||||
child: isGif && isDirectUrl
|
||||
// Use Image.network for GIFs to preserve animation
|
||||
? Image.network(
|
||||
imageUrl,
|
||||
fit: BoxFit.cover,
|
||||
placeholder: (context, url) => _buildImagePlaceholder(),
|
||||
errorWidget: (context, url, error) => _buildImageError(),
|
||||
loadingBuilder: (context, child, progress) {
|
||||
if (progress == null) return child;
|
||||
return _buildImagePlaceholder();
|
||||
},
|
||||
errorBuilder: (context, error, stack) => _buildImageError(),
|
||||
)
|
||||
: S3Image(
|
||||
imageUrl: imageUrl,
|
||||
fit: BoxFit.cover,
|
||||
placeholder: (_) => _buildImagePlaceholder(),
|
||||
errorWidget: (_) => _buildImageError(),
|
||||
),
|
||||
: isDirectUrl
|
||||
? CachedNetworkImage(
|
||||
imageUrl: imageUrl,
|
||||
fit: BoxFit.cover,
|
||||
placeholder: (context, url) => _buildImagePlaceholder(),
|
||||
errorWidget: (context, url, error) => _buildImageError(),
|
||||
)
|
||||
: S3Image(
|
||||
imageUrl: imageUrl,
|
||||
fit: BoxFit.cover,
|
||||
placeholder: (_) => _buildImagePlaceholder(),
|
||||
errorWidget: (_) => _buildImageError(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -942,23 +959,16 @@ class _ChatScreenState extends ConsumerState<ChatScreen> {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
senderName,
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Fractul',
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.primaryDark,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
const Text(
|
||||
'He/Him',
|
||||
style: TextStyle(
|
||||
fontFamily: 'SourceSerif4',
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: AppColors.primaryDark,
|
||||
Flexible(
|
||||
child: Text(
|
||||
senderName,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Fractul',
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.primaryDark,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
@@ -1047,16 +1057,6 @@ class _ChatScreenState extends ConsumerState<ChatScreen> {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
const Text(
|
||||
'He/Him',
|
||||
style: TextStyle(
|
||||
fontFamily: 'SourceSerif4',
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: AppColors.primaryDark,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
timestamp,
|
||||
style: const TextStyle(
|
||||
|
||||
Reference in New Issue
Block a user