feat: 添加首页图片选择功能(拍照/相册)
This commit is contained in:
@@ -3,6 +3,7 @@ import 'dart:convert';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:social_app/core/api/i_api_client.dart';
|
||||
import 'package:social_app/core/api/mock_api_client.dart';
|
||||
|
||||
@@ -41,9 +42,9 @@ class AgUiService {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> sendMessage(String content) async {
|
||||
Future<void> sendMessage(String content, {List<XFile>? images}) async {
|
||||
final streamToken = ++_activeStreamToken;
|
||||
final runInput = _buildRunInput(content: content);
|
||||
final runInput = await _buildRunInput(content: content, images: images);
|
||||
final response = await _apiClient.post<Map<String, dynamic>>(
|
||||
'/api/v1/agent/runs',
|
||||
data: runInput,
|
||||
@@ -238,15 +239,50 @@ class AgUiService {
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> _buildRunInput({required String content}) {
|
||||
Future<Map<String, dynamic>> _buildRunInput({
|
||||
required String content,
|
||||
List<XFile>? images,
|
||||
}) async {
|
||||
final threadId = _threadId ?? _newUuid();
|
||||
final runId = _nextId(_runIdPrefix);
|
||||
|
||||
final contentBlocks = <Map<String, dynamic>>[];
|
||||
|
||||
if (content.isNotEmpty) {
|
||||
contentBlocks.add({'type': 'text', 'text': content});
|
||||
}
|
||||
|
||||
if (images != null && images.isNotEmpty) {
|
||||
for (final image in images) {
|
||||
final bytes = await image.readAsBytes();
|
||||
final base64 = base64Encode(bytes);
|
||||
contentBlocks.add({
|
||||
'type': 'image',
|
||||
'source': {
|
||||
'type': 'base64',
|
||||
'media_type': 'image/jpeg',
|
||||
'data': base64,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
final dynamic messageContent;
|
||||
if (contentBlocks.isEmpty) {
|
||||
messageContent = '';
|
||||
} else if (contentBlocks.length == 1 &&
|
||||
contentBlocks[0]['type'] == 'text') {
|
||||
messageContent = contentBlocks[0]['text'];
|
||||
} else {
|
||||
messageContent = contentBlocks;
|
||||
}
|
||||
|
||||
return {
|
||||
'threadId': threadId,
|
||||
'runId': runId,
|
||||
'state': <String, dynamic>{},
|
||||
'messages': [
|
||||
{'id': _nextId('user_'), 'role': 'user', 'content': content},
|
||||
{'id': _nextId('user_'), 'role': 'user', 'content': messageContent},
|
||||
],
|
||||
'tools': _buildTools(),
|
||||
'context': <Map<String, dynamic>>[],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:social_app/core/api/i_api_client.dart';
|
||||
import 'package:social_app/core/api/mock_api_client.dart';
|
||||
import 'package:social_app/core/di/injection.dart';
|
||||
@@ -367,7 +368,7 @@ class ChatBloc extends Cubit<ChatState> {
|
||||
.reduce((a, b) => a.isBefore(b) ? a : b);
|
||||
}
|
||||
|
||||
Future<void> sendMessage(String content) async {
|
||||
Future<void> sendMessage(String content, {List<XFile>? images}) async {
|
||||
final userMessage = TextMessageItem(
|
||||
id: 'user-${DateTime.now().millisecondsSinceEpoch}',
|
||||
content: content,
|
||||
@@ -385,7 +386,7 @@ class ChatBloc extends Cubit<ChatState> {
|
||||
),
|
||||
);
|
||||
try {
|
||||
await _service.sendMessage(content);
|
||||
await _service.sendMessage(content, images: images);
|
||||
} catch (error) {
|
||||
emit(
|
||||
state.copyWith(
|
||||
|
||||
Reference in New Issue
Block a user