Skip to content

Commit 63a07af

Browse files
download function added
1 parent 5052beb commit 63a07af

File tree

1 file changed

+386
-0
lines changed

1 file changed

+386
-0
lines changed

lib/Pages/home_page.dart

Lines changed: 386 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,386 @@
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

Comments
 (0)