Working project

This commit is contained in:
2024-10-09 18:40:11 -06:00
commit 670cb24095
70 changed files with 154073 additions and 0 deletions
+165
View File
@@ -0,0 +1,165 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'shorten_service.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: Home(),
);
}
}
class Home extends StatefulWidget {
const Home({super.key});
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
late final TextEditingController controller;
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
String? shortenedUrl;
bool loading = false;
@override
void initState() {
super.initState();
controller = TextEditingController();
}
@override
void dispose() {
super.dispose();
controller.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Stack(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'Url shortner',
style: TextStyle(fontSize: 24),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const SizedBox(width: 30),
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 300),
child: Form(
key: formKey,
child: TextFormField(
controller: controller,
onFieldSubmitted: loading ? null : (_) => processUrl(),
validator: (String? url) {
try {
if (url == null || url.isEmpty) {
return 'No url entered.';
}
final Uri uri = Uri.parse(url);
if (!uri.hasScheme || (!uri.isScheme('HTTP') && !uri.isScheme('HTTPS'))) {
throw const FormatException();
}
return null;
} on FormatException {
return 'Bad URL';
}
},
),
),
),
IconButton(
icon: const Icon(Icons.arrow_circle_right_rounded),
onPressed: loading ? null : () => processUrl(),
),
],
),
AnimatedOpacity(
opacity: shortenedUrl == null ? 0.0 : 1.0,
duration: const Duration(milliseconds: 200),
child: Padding(
padding: const EdgeInsets.only(top: 14.0),
child: Column(
children: <Widget>[
const Text('Short URL:'),
InkWell(
onTap: shortenedUrl == null ? null : () => launchUrl(Uri.parse(shortenedUrl!)),
child: Text(
shortenedUrl ?? '',
style: const TextStyle(color: Colors.blue, fontSize: 24),
),
),
],
),
),
),
],
),
Center(
child: AnimatedOpacity(
opacity: loading ? 1.0 : 0.0,
duration: const Duration(milliseconds: 200),
child: const CircularProgressIndicator(),
),
)
],
),
),
);
}
Future<void> processUrl() async {
try {
assert(formKey.currentState != null, 'Could not validate form, formKey currentState is null');
if (loading) {
return;
}
setState(() => loading = true);
final bool isValid = formKey.currentState!.validate();
if (!isValid) {
setState(() => loading = false);
return;
}
final String? shortUrl = await shortenUrl(controller.text);
if (shortUrl != null) {
setState(() {
shortenedUrl = shortUrl;
loading = false;
});
} else {
// show error
setState(() {
shortenedUrl = null;
loading = false;
});
}
} catch (err, st) {
if (kDebugMode) {
print(st);
print('An error occurred trying to shorten the url: $err');
}
setState(() => loading = false);
}
}
}
+23
View File
@@ -0,0 +1,23 @@
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
BaseOptions dioOptions = BaseOptions(baseUrl: 'http://localhost:8080');
Future<String?> shortenUrl(String url) async {
try {
assert(url.isNotEmpty);
final Response<String> res = await Dio(dioOptions).post('/', data: <String, String>{'url': url});
final Map<String, dynamic> json = jsonDecode(res.data ?? '') as Map<String, dynamic>;
print(json);
return json['url'] as String?;
} catch (err, st) {
if (kDebugMode) {
print('Encountered an error:');
print(st);
print(err);
}
return null;
}
}
+1
View File
@@ -0,0 +1 @@
class ShrinkRay {}