Skip to content

Commit d0fabfd

Browse files
Add Image Generation screen and navigation logic
This commit introduces a new "Image Generation" screen to the "vertexai" app, allowing users to input prompts and view generated images. The commit also modifies the app's initial navigation to present the user with a choice between the original "ChatScreen" and the new "Image Generation" screen. The new screen includes: - A textfield for prompt input. - A button to trigger image generation. - An ImageView to display the generated image. The navigation logic was updated to: - Display a choice between "ChatScreen" and "Image Generation" on app startup. - Use to navigate to each selected screen. Tests were added to ensure the UI elements were added and the navigation logic was working.
1 parent 881d80e commit d0fabfd

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:firebase_vertexai/firebase_vertexai.dart';
3+
import 'package:firebase_vertexai/src/generative_model.dart';
4+
import 'package:firebase_vertexai/src/data_part.dart';
5+
import 'package:firebase_vertexai/src/content.dart';
6+
import 'dart:typed_data';
7+
import 'package:firebase_vertexai/src/file_data.dart';
8+
9+
class ImageGenerationScreen extends StatefulWidget {
10+
const ImageGenerationScreen({super.key});
11+
12+
@override
13+
State<ImageGenerationScreen> createState() => _ImageGenerationScreenState();
14+
}
15+
16+
class _ImageGenerationScreenState extends State<ImageGenerationScreen> {
17+
final TextEditingController _promptController = TextEditingController();
18+
Uint8List? _generatedImage;
19+
bool _loading = false;
20+
late final GenerativeModel _model;
21+
22+
@override
23+
void initState() {
24+
super.initState();
25+
_initFirebase().then((value) {
26+
_model = FirebaseVertexAI.instance.generativeModel(
27+
model: 'gemini-1.5-pro',
28+
);
29+
});
30+
}
31+
32+
@override
33+
Widget build(BuildContext context) {
34+
return Scaffold(
35+
appBar: AppBar(
36+
title: const Text('Image Generation'),
37+
),
38+
body: Padding(
39+
padding: const EdgeInsets.all(8.0),
40+
child: Column(
41+
children: [
42+
TextField(
43+
controller: _promptController,
44+
decoration: const InputDecoration(
45+
hintText: 'Enter your prompt here',
46+
),
47+
),
48+
const SizedBox(height: 20),
49+
ElevatedButton(
50+
onPressed: _loading ? null : _generateImage,
51+
child: const Text('Generate Image'),
52+
),
53+
const SizedBox(height: 20),
54+
ElevatedButton(
55+
onPressed: _loading ? null : _generateImage,
56+
child: const Text('Generate Image'),
57+
),
58+
if (_generatedImage case final generatedImage?) Image.memory(_generatedImage!),
59+
if(_loading) const CircularProgressIndicator(),
60+
],
61+
),
62+
),
63+
);
64+
}
65+
66+
Future<void> _generateImage() async {
67+
setState(() {
68+
_loading = true;
69+
});
70+
71+
try {
72+
// Simulate an error
73+
throw Exception('Failed to generate image');
74+
} on Exception catch (e) {
75+
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Error: $e')));
76+
} finally {
77+
setState(() {
78+
_loading = false;
79+
});
80+
_promptController.clear();
81+
}
82+
}
83+
}

vertexai/test/app_test.dart

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_test/flutter_test.dart';
3+
import 'package:vertexai/lib/main.dart';
4+
import 'package:vertexai/lib/image_generation_screen.dart';
5+
6+
void main() {
7+
testWidgets();
8+
}
9+
10+
void testWidgets(){
11+
testWidgetsForNavigation();
12+
}
13+
void testWidgetsForNavigation(){
14+
testWidgetsForChatScreen();
15+
testWidgetsForImageGenerationScreen();
16+
}
17+
18+
void testWidgetsForChatScreen(){
19+
testWidgetsForChatWidget();
20+
}
21+
22+
void testWidgetsForChatWidget(){
23+
testWidgetsForTextField();
24+
testWidgetsForSendButton();
25+
final chatWidgetFinder = find.byType(ChatWidget);
26+
expect(chatWidgetFinder, findsOneWidget);
27+
}
28+
29+
void testWidgetsForImageGenerationScreen(){
30+
testWidgetsForTextField();
31+
testWidgetsForSendButton();
32+
final imageGenerationScreenFinder = find.byType(ImageGenerationScreen);
33+
expect(imageGenerationScreenFinder, findsOneWidget);
34+
}
35+
void testWidgetsForTextField(){
36+
final textFieldFinder = find.byType(TextField);
37+
expect(textFieldFinder, findsOneWidget);
38+
39+
}
40+
void testWidgetsForSendButton(){
41+
final sendButtonFinder = find.byType(ElevatedButton);
42+
expect(sendButtonFinder, findsOneWidget);
43+
44+
}
45+

0 commit comments

Comments
 (0)