Skip to content

Commit d07d4a5

Browse files
authored
Merge pull request #2 from apeynado/apeynado/main
fixing late initialization error on live api service
2 parents 108e8f7 + a960ac9 commit d07d4a5

File tree

2 files changed

+45
-51
lines changed

2 files changed

+45
-51
lines changed

firebase_ai_logic_showcase/lib/demos/live_api/live_api_demo.dart

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ import 'utilities/utilities.dart';
2323
import 'firebaseai_live_api_service.dart';
2424

2525
class LiveAPIDemo extends ConsumerStatefulWidget {
26-
const LiveAPIDemo({super.key, this.isSelected = false});
27-
final bool isSelected;
26+
const LiveAPIDemo({super.key});
2827

2928
@override
3029
ConsumerState<LiveAPIDemo> createState() => _LiveAPIDemoState();
@@ -45,9 +44,7 @@ class _LiveAPIDemoState extends ConsumerState<LiveAPIDemo> {
4544
late final VideoInput _videoInput = VideoInput();
4645

4746
// Initialization flags.
48-
bool _audioIsInitialized = false;
4947
bool _videoIsInitialized = false;
50-
static bool _hasBeenSelected = false;
5148

5249
// UI State flags.
5350
bool _isConnecting = false; // True when setting up the Gemini session.
@@ -66,24 +63,19 @@ class _LiveAPIDemoState extends ConsumerState<LiveAPIDemo> {
6663
@override
6764
void didUpdateWidget(LiveAPIDemo oldWidget) {
6865
super.didUpdateWidget(oldWidget);
69-
if (widget.isSelected != oldWidget.isSelected) {
70-
_checkAndInitializeIO();
71-
}
66+
_checkAndInitializeIO();
7267
}
7368

7469
Future<void> _checkAndInitializeIO() async {
75-
if (widget.isSelected && !_hasBeenSelected) {
76-
_hasBeenSelected = true;
77-
await _initializeAudio();
78-
await _initializeVideo();
79-
_liveApiService = LiveApiService(
80-
audioOutput: _audioOutput,
81-
ref: ref, // Pass the ref to the service
82-
onImageLoadingChange: _onImageLoadingChange,
83-
onImageGenerated: _onImageGenerated,
84-
onError: _showErrorSnackBar,
85-
);
86-
}
70+
await _initializeAudio();
71+
await _initializeVideo();
72+
_liveApiService = LiveApiService(
73+
audioOutput: _audioOutput,
74+
ref: ref, // Pass the ref to the service
75+
onImageLoadingChange: _onImageLoadingChange,
76+
onImageGenerated: _onImageGenerated,
77+
onError: _showErrorSnackBar,
78+
);
8779
}
8880

8981
@override

firebase_ai_logic_showcase/lib/flutter_firebase_ai_demo.dart

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,27 @@ class DemoHomeScreen extends StatefulWidget {
2727

2828
class _DemoHomeScreenState extends State<DemoHomeScreen> {
2929
int _selectedIndex = 0;
30+
final List<({Widget icon, String label, Widget? selectedIcon})> destinations =
31+
[
32+
(icon: const Icon(Icons.chat), label: 'Chat', selectedIcon: null),
33+
(
34+
icon: const Icon(Icons.video_chat),
35+
label: 'Live API',
36+
selectedIcon: null,
37+
),
38+
(
39+
icon: const Icon(Icons.photo_library),
40+
label: 'Multimodal',
41+
selectedIcon: null,
42+
),
43+
(
44+
icon: RichText(
45+
text: const TextSpan(style: TextStyle(fontSize: 24.0), text: '🍌'),
46+
),
47+
label: 'Nano Banana',
48+
selectedIcon: null,
49+
),
50+
];
3051

3152
void _onItemTapped(int index) {
3253
setState(() {
@@ -36,35 +57,12 @@ class _DemoHomeScreenState extends State<DemoHomeScreen> {
3657

3758
@override
3859
Widget build(BuildContext context) {
39-
final List<Widget> demoPages = <Widget>[
40-
const ChatDemo(),
41-
LiveAPIDemo(isSelected: _selectedIndex == 1),
42-
const MultimodalDemo(),
43-
ChatDemoNano(isSelected: _selectedIndex == 3),
44-
];
45-
46-
final List<({Widget icon, String label, Widget? selectedIcon})> destinations = [
47-
(icon: const Icon(Icons.chat), label: 'Chat', selectedIcon: null),
48-
(icon: const Icon(Icons.video_chat), label: 'Live API', selectedIcon: null),
49-
(icon: const Icon(Icons.photo_library), label: 'Multimodal', selectedIcon: null),
50-
(
51-
icon: RichText(
52-
text: const TextSpan(
53-
style: TextStyle(fontSize: 24.0),
54-
text: '🍌',
55-
),
56-
),
57-
label: 'Nano Banana',
58-
selectedIcon: null
59-
),
60-
];
61-
6260
return LayoutBuilder(
6361
builder: (context, constraints) {
6462
if (constraints.maxWidth < 600) {
6563
// Use BottomNavigationBar for smaller screens
6664
return Scaffold(
67-
body: IndexedStack(index: _selectedIndex, children: demoPages),
65+
body: demoPages[_selectedIndex],
6866
bottomNavigationBar: BottomNavigationBar(
6967
type: BottomNavigationBarType.fixed,
7068
items: destinations
@@ -94,20 +92,17 @@ class _DemoHomeScreenState extends State<DemoHomeScreen> {
9492
(e) => NavigationRailDestination(
9593
padding: const EdgeInsets.symmetric(vertical: 8.0),
9694
icon: e.icon,
97-
label: Text(e.label.replaceAll(' ', '\n'),
98-
textAlign: TextAlign.center),
95+
label: Text(
96+
e.label.replaceAll(' ', '\n'),
97+
textAlign: TextAlign.center,
98+
),
9999
selectedIcon: e.selectedIcon,
100100
),
101101
)
102102
.toList(),
103103
),
104104
const VerticalDivider(thickness: 1, width: 1),
105-
Expanded(
106-
child: IndexedStack(
107-
index: _selectedIndex,
108-
children: demoPages,
109-
),
110-
),
105+
Expanded(child: demoPages[_selectedIndex]),
111106
],
112107
),
113108
);
@@ -116,3 +111,10 @@ class _DemoHomeScreenState extends State<DemoHomeScreen> {
116111
);
117112
}
118113
}
114+
115+
final List<Widget> demoPages = <Widget>[
116+
const ChatDemo(),
117+
LiveAPIDemo(),
118+
const MultimodalDemo(),
119+
ChatDemoNano(),
120+
];

0 commit comments

Comments
 (0)