Skip to content

Commit 899c493

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, but then the user requested to delete it.
1 parent 881d80e commit 899c493

File tree

2 files changed

+124
-5
lines changed

2 files changed

+124
-5
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/lib/main.dart

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,22 @@ import 'package:flutter/services.dart';
1717
import 'package:flutter_markdown/flutter_markdown.dart';
1818
import 'package:firebase_vertexai/firebase_vertexai.dart';
1919
import 'package:firebase_core/firebase_core.dart';
20+
import 'package:vertexai/lib/image_generation_screen.dart';
2021

2122
void main() {
2223
runApp(const GenerativeAISample());
2324
}
2425

25-
class GenerativeAISample extends StatelessWidget {
26+
class GenerativeAISample extends StatefulWidget {
2627
const GenerativeAISample({super.key});
2728

2829
@override
29-
Widget build(BuildContext context) {
30+
State<GenerativeAISample> createState() => _GenerativeAISampleState();
31+
}
32+
33+
class _GenerativeAISampleState extends State<GenerativeAISample>{
34+
@override
35+
Widget build(BuildContext context){
3036
return MaterialApp(
3137
title: 'Flutter + Vertex AI',
3238
theme: ThemeData(
@@ -36,9 +42,39 @@ class GenerativeAISample extends StatelessWidget {
3642
),
3743
useMaterial3: true,
3844
),
39-
home: const ChatScreen(title: 'Flutter + Vertex AI'),
40-
);
41-
}
45+
home: Scaffold(
46+
appBar: AppBar(
47+
title: const Text('Flutter + Vertex AI'),
48+
),
49+
body: Center(
50+
child: Row(
51+
mainAxisAlignment: MainAxisAlignment.center,
52+
children: [
53+
ElevatedButton(
54+
onPressed: () {
55+
Navigator.push(
56+
context,
57+
MaterialPageRoute(builder: (context) => const ChatScreen(title: 'Flutter + Vertex AI')),
58+
);
59+
},
60+
child: const Text('Chat'),
61+
),
62+
const SizedBox(width: 20),
63+
ElevatedButton(
64+
onPressed: () {
65+
Navigator.push(
66+
context,
67+
MaterialPageRoute(builder: (context) => const ImageGenerationScreen()),
68+
);
69+
},
70+
child: const Text('Image Generation'),
71+
),
72+
],
73+
),
74+
),
75+
),
76+
);
77+
}
4278
}
4379

4480
class ChatScreen extends StatefulWidget {

0 commit comments

Comments
 (0)