1
+ import 'dart:async' ;
2
+ import 'dart:ui' as ui;
3
+
4
+ import 'package:brain_fusion/brain_fusion.dart' ;
5
+ import 'package:flutter/foundation.dart' ;
6
+ import 'package:flutter/material.dart' ;
7
+ import 'package:fluttertoast/fluttertoast.dart' ;
8
+ import 'package:image_gallery_saver/image_gallery_saver.dart' ;
9
+ import 'package:lottie/lottie.dart' ;
10
+ import 'package:text_to_image_gen/Pages/about_page.dart' ;
11
+ import 'package:url_launcher/url_launcher.dart' ;
12
+ import 'package:flutter/rendering.dart' ;
13
+
14
+ class HomePage extends StatefulWidget {
15
+ const HomePage ({Key ? key}) : super (key: key);
16
+
17
+ @override
18
+ State <HomePage > createState () => _HomePageState ();
19
+ }
20
+
21
+ class _HomePageState extends State <HomePage > {
22
+ final TextEditingController _queryController = TextEditingController ();
23
+
24
+ final AI _ai = AI ();
25
+
26
+ Future <Uint8List > _generate (String query) async {
27
+ Uint8List image = await _ai.runAI (query, AIStyle .render3D);
28
+ return image;
29
+ }
30
+
31
+ final GlobalKey _globalKey = GlobalKey ();
32
+
33
+ bool _isDownloading = false ;
34
+ bool _isDownloadInitiated = false ;
35
+ bool run = false ;
36
+ String query = "" ;
37
+
38
+ @override
39
+ void dispose () {
40
+ _queryController.dispose ();
41
+ super .dispose ();
42
+ }
43
+
44
+ var scaffoldKey = GlobalKey <ScaffoldState >();
45
+ @override
46
+ Widget build (BuildContext context) {
47
+ return Scaffold (
48
+ key: scaffoldKey,
49
+ backgroundColor: Colors .deepPurple.shade50,
50
+ appBar: AppBar (
51
+ iconTheme: IconThemeData (color: Colors .deepPurple.shade400),
52
+ backgroundColor: Colors .transparent,
53
+ title: RichText (
54
+ text: TextSpan (
55
+ text: 'Tex' ,
56
+ style: TextStyle (color: Colors .amber.shade900, fontWeight: FontWeight .w500, fontSize: 18 ),
57
+ children: [
58
+ TextSpan (
59
+ text: 'Fusion' ,
60
+ style: TextStyle (color: Colors .deepPurple.shade500, fontWeight: FontWeight .w500, fontSize: 18 ),
61
+ )
62
+ ]
63
+ ),
64
+ ),
65
+ elevation: 0 ,
66
+ centerTitle: true ,
67
+ leading: InkWell (
68
+ onTap: (){
69
+ scaffoldKey.currentState? .openDrawer ();
70
+ },
71
+ child: Padding (
72
+ padding: const EdgeInsets .all (8.0 ),
73
+ child: Lottie .asset (
74
+ 'assets/animations/me.json' ,
75
+ repeat: true ,
76
+ reverse: true ,
77
+ animate: true ,
78
+ ),
79
+ ),
80
+ ),
81
+ actions: [
82
+ InkWell (
83
+ onTap: (){
84
+ Navigator .push (context, MaterialPageRoute (builder: (context) => const AboutPage ()));
85
+ },
86
+ child: Padding (
87
+ padding: const EdgeInsets .all (12 ),
88
+ child: Lottie .asset (
89
+ 'assets/animations/set.json' ,
90
+ repeat: true ,
91
+ reverse: true ,
92
+ animate: true ,
93
+ ),
94
+ ),
95
+ ),
96
+ ],
97
+ ),
98
+ drawer: Drawer (
99
+ child: Container (
100
+ color: Colors .deepPurple.shade50,
101
+ child: Column (
102
+ children: [
103
+ Container (
104
+ color: Colors .deepPurple.shade50,
105
+ child: DrawerHeader (
106
+ child: Center (
107
+ child: Text (
108
+ "TexFusion AI App" ,
109
+ style: TextStyle (
110
+ fontSize: 18 , color: Colors .deepPurple.shade400),
111
+ ),
112
+ ),
113
+ ),
114
+ ),
115
+ ListTile (
116
+ leading: const Icon (
117
+ Icons .source_rounded,
118
+ color: Colors .black54,
119
+ ),
120
+ title: Text (
121
+ "Source Code" ,
122
+ style: TextStyle (
123
+ fontSize: 16 , color: Colors .deepPurple.shade400),
124
+ ),
125
+ onTap: () async {
126
+ final Uri url = Uri .parse (
127
+ 'https://github.com/VikramadityaDev/text_to_image_gen/' );
128
+ if (! await launchUrl (url,
129
+ mode: LaunchMode .externalApplication)) {
130
+ throw Exception ('Could not launch $url ' );
131
+ }
132
+ },
133
+ ),
134
+ ListTile (
135
+ leading: const Icon (
136
+ Icons .update,
137
+ color: Colors .black54,
138
+ ),
139
+ title: Text (
140
+ "Check for update" ,
141
+ style: TextStyle (
142
+ fontSize: 16 , color: Colors .deepPurple.shade400),
143
+ ),
144
+ onTap: () async {
145
+ final Uri url =
146
+ Uri .parse ('https://telegram.me/vikimediaofficial/' );
147
+ if (! await launchUrl (url,
148
+ mode: LaunchMode .externalApplication)) {
149
+ throw Exception ('Could not launch $url ' );
150
+ }
151
+ },
152
+ ),
153
+ Expanded (
154
+ child: Padding (
155
+ padding: const EdgeInsets .all (10 ),
156
+ child: Align (
157
+ alignment: Alignment .bottomCenter,
158
+ child: Text (
159
+ 'v1.0.2' ,
160
+ style: TextStyle (
161
+ fontSize: 16 ,
162
+ color: Colors .deepPurple.shade400,
163
+ fontWeight: FontWeight .w500),
164
+ ),
165
+ ),
166
+ ),
167
+ ),
168
+ ],
169
+ ),
170
+ ),
171
+ ),
172
+ body: SingleChildScrollView (
173
+ physics: const BouncingScrollPhysics (),
174
+ child: Column (
175
+ mainAxisAlignment: MainAxisAlignment .center,
176
+ crossAxisAlignment: CrossAxisAlignment .center,
177
+ children: < Widget > [
178
+ const SizedBox (
179
+ height: 10 ,
180
+ ),
181
+ Padding (
182
+ padding: const EdgeInsets .all (6.0 ),
183
+ child: TextField (
184
+ keyboardType: TextInputType .multiline,
185
+ minLines: 1 ,
186
+ maxLines: 10 ,
187
+ controller: _queryController,
188
+ decoration: InputDecoration (
189
+ hintText: 'Enter your imagination...' ,
190
+ enabledBorder: OutlineInputBorder (
191
+ borderRadius: BorderRadius .circular (8 ),
192
+ borderSide: BorderSide (
193
+ width: 1.5 ,
194
+ color: Colors .deepPurple.shade400,
195
+ ),
196
+ ),
197
+ focusedBorder: OutlineInputBorder (
198
+ borderRadius: BorderRadius .circular (8 ),
199
+ borderSide: BorderSide (
200
+ width: 1.5 ,
201
+ color: Colors .deepPurple.shade400,
202
+ ),
203
+ ),
204
+ ),
205
+ ),
206
+ ),
207
+ Padding (
208
+ padding: const EdgeInsets .all (5 ),
209
+ child: SizedBox (
210
+ height: MediaQuery .of (context).size.height / 1.9 ,
211
+ width: MediaQuery .of (context).size.width,
212
+ child: run
213
+ ? FutureBuilder <Uint8List >(
214
+ future: _generate (_queryController.text),
215
+ builder: (context, snapshot) {
216
+ if (snapshot.connectionState ==
217
+ ConnectionState .waiting) {
218
+ return Padding (
219
+ padding: const EdgeInsets .all (120.0 ),
220
+ child: Lottie .asset (
221
+ 'assets/animations/loading.json' ,
222
+ repeat: true ,
223
+ reverse: true ,
224
+ animate: true ,
225
+ ),
226
+ );
227
+ } else if (snapshot.hasError) {
228
+ return const Center (
229
+ child: Text (
230
+ 'Something went wrong. Please Re-generate.' ,
231
+ ),
232
+ );
233
+ } else if (snapshot.hasData) {
234
+ return RepaintBoundary (
235
+ key: _globalKey,
236
+ child: InkWell (
237
+ onTap: () {
238
+ _saveScreen ();
239
+ },
240
+ child: Image .memory (snapshot.data! ),
241
+ ),
242
+ );
243
+ } else {
244
+ return Container ();
245
+ }
246
+ },
247
+ )
248
+ : const Center (
249
+ child: Text (
250
+ 'See Magic Here 🪄' ,
251
+ style: TextStyle (
252
+ fontWeight: FontWeight .w500,
253
+ fontSize: 16 ,
254
+ ),
255
+ ),
256
+ ),
257
+ ),
258
+ ),
259
+ SizedBox (
260
+ height: MediaQuery .of (context).size.width / 5.5 ,
261
+ ),
262
+ const Text (
263
+ 'Click the image to save in Gallery.' ,
264
+ softWrap: true ,
265
+ style: TextStyle (fontSize: 15 , fontWeight: FontWeight .w500),
266
+ ),
267
+ const SizedBox (
268
+ height: 5 ,
269
+ ),
270
+ const SizedBox (
271
+ height: 15 ,
272
+ ),
273
+ Padding (
274
+ padding: const EdgeInsets .only (left: 80 , right: 80 ),
275
+ child: ElevatedButton (
276
+ onPressed: () {
277
+ String newQuery = _queryController.text;
278
+ if (newQuery.isNotEmpty) {
279
+ setState (() {
280
+ query = newQuery;
281
+ run = true ;
282
+ });
283
+ } else {
284
+ if (newQuery.isEmpty) {
285
+ Fluttertoast .showToast (
286
+ msg: 'Query is empty !!' ,
287
+ gravity: ToastGravity .BOTTOM ,
288
+ backgroundColor: Colors .red,
289
+ );
290
+ print ('Query is empty !!' );
291
+ }
292
+ }
293
+ },
294
+ style: ButtonStyle (
295
+ padding: MaterialStateProperty .all (
296
+ const EdgeInsets .all (0.0 ),
297
+ ),
298
+ elevation: MaterialStateProperty .all (0 ),
299
+ shape: MaterialStateProperty .all (
300
+ RoundedRectangleBorder (
301
+ borderRadius: BorderRadius .circular (5.0 ),
302
+ ),
303
+ ),
304
+ ),
305
+ child: Ink (
306
+ decoration: BoxDecoration (
307
+ gradient: LinearGradient (
308
+ colors: [
309
+ Colors .deepPurple.shade400,
310
+ Colors .deepPurpleAccent.shade200,
311
+ ],
312
+ ),
313
+ borderRadius: const BorderRadius .all (
314
+ Radius .circular (5.0 ),
315
+ ),
316
+ ),
317
+ child: Container (
318
+ constraints: const BoxConstraints (
319
+ minWidth: 88.0 ,
320
+ minHeight: 45.0 ,
321
+ ),
322
+ alignment: Alignment .center,
323
+ child: const Text (
324
+ 'Generate' ,
325
+ textAlign: TextAlign .center,
326
+ style: TextStyle (fontSize: 18 ),
327
+ ),
328
+ ),
329
+ ),
330
+ ),
331
+ ),
332
+ ],
333
+ ),
334
+ ),
335
+ bottomNavigationBar: const Padding (
336
+ padding: EdgeInsets .only (bottom: 8 ),
337
+ child: Text (
338
+ "Made With Love ❤️ VikiMedia" ,
339
+ textAlign: TextAlign .center,
340
+ style: TextStyle (fontSize: 12 ),
341
+ ),
342
+ ),
343
+ );
344
+ }
345
+ _saveScreen () async {
346
+ if (_isDownloading) {
347
+ // Do nothing if a download is already in progress.
348
+ Fluttertoast .showToast (
349
+ msg: 'Download in progress. Please wait.' ,
350
+ gravity: ToastGravity .BOTTOM ,
351
+ backgroundColor: Colors .amber,
352
+ timeInSecForIosWeb: 3 ,
353
+ );
354
+ return ;
355
+ }
356
+ if (_isDownloadInitiated) {
357
+ return ;
358
+ }
359
+ _isDownloadInitiated = true ;
360
+ Fluttertoast .showToast (
361
+ msg: 'Download Started !' ,
362
+ gravity: ToastGravity .BOTTOM ,
363
+ timeInSecForIosWeb: 3 ,
364
+ );
365
+ _isDownloading = true ;
366
+ RenderRepaintBoundary boundary =
367
+ _globalKey.currentContext! .findRenderObject () as RenderRepaintBoundary ;
368
+ ui.Image image = await boundary.toImage (pixelRatio: 12 );
369
+ ByteData ? byteData = await (image.toByteData (format: ui.ImageByteFormat .png));
370
+ if (byteData != null ) {
371
+ final result = await ImageGallerySaver .saveImage (
372
+ byteData.buffer.asUint8List (),
373
+ quality: 100 ,
374
+ );
375
+ print (result);
376
+ Fluttertoast .showToast (
377
+ msg: 'Image Successfully Saved To Gallery.' ,
378
+ gravity: ToastGravity .BOTTOM ,
379
+ backgroundColor: Colors .green,
380
+ timeInSecForIosWeb: 3 ,
381
+ );
382
+ }
383
+ _isDownloadInitiated = false ;
384
+ _isDownloading = false ;
385
+ }
386
+ }
0 commit comments