aboutsummaryrefslogtreecommitdiffhomepage
path: root/main.dart
diff options
context:
space:
mode:
Diffstat (limited to 'main.dart')
-rw-r--r--main.dart285
1 files changed, 285 insertions, 0 deletions
diff --git a/main.dart b/main.dart
new file mode 100644
index 0000000..266b670
--- /dev/null
+++ b/main.dart
@@ -0,0 +1,285 @@
+import 'package:flutter/material.dart';
+import 'dart:io';
+
+void main() {
+ runApp(const MyApp());
+}
+
+class MyApp extends StatelessWidget {
+ const MyApp({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ title: 'Flutter Demo',
+ theme: ThemeData(
+ brightness: Brightness.light,
+ ),
+ darkTheme: ThemeData(
+ brightness: Brightness.dark,
+ ),
+ themeMode: ThemeMode.dark,
+ home: const MyHomePage(title: 'Socket Demo'),
+ );
+ }
+}
+
+class MyHomePage extends StatefulWidget {
+ const MyHomePage({super.key, required this.title});
+
+ final String title;
+
+ @override
+ State<MyHomePage> createState() => _MyHomePageState();
+}
+
+class _MyHomePageState extends State<MyHomePage> {
+ late Socket _socket;
+ final TextEditingController _inputController = TextEditingController();
+ final List<String> _msgs = [];
+ String address = "";
+
+ @override
+ void initState() {
+ super.initState();
+ _connect();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ backgroundColor: Colors.purple,
+ title: Text(widget.title),
+ ),
+ body: Column(children: [
+ Expanded(
+ child: ListView.builder(
+ padding: EdgeInsets.all(10.0),
+ itemCount: _msgs.length,
+ itemBuilder: (context, index) {
+ var msg = _msgs[index];
+ String user = "";
+ String data = "";
+ int i;
+ for (i = 0; i < msg.length; i++) {
+ if (msg[i] == '=') {
+ i++;
+ break;
+ }
+ user += msg[i];
+ }
+ for (; i < msg.length; i++) {
+ data += msg[i];
+ }
+
+ if (user == address) {
+ return BubbleSend(message: data, user: user);
+ } else {
+ return BubbleReceive(message: data, user: user);
+ }
+ },
+ )),
+ Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Row(
+ children: [
+ Expanded(
+ child: TextField(
+ controller: _inputController,
+ onSubmitted: (value) {
+ _send();
+ },
+ decoration: const InputDecoration(
+ border: OutlineInputBorder(),
+ labelText: 'Enter message',
+ ),
+ ),
+ ),
+ IconButton(
+ icon: Icon(Icons.send),
+ onPressed: () {
+ _send();
+ },
+ ),
+ ],
+ ),
+ ),
+ ]),
+ );
+ }
+
+ void _connect() async {
+ try {
+ _socket = await Socket.connect("127.0.0.1", 7654);
+ address = "${_socket.address.address}:${_socket.port}";
+ print("my address: $address");
+ toast("Connected to 127.0.0.1:7654", 0);
+
+ _socket.listen(
+ (data) {
+ final message = String.fromCharCodes(data).trim();
+ print('received: $message');
+ if (message[0] == '!') {
+ String name = "";
+ for (int i = 1; i < message.length; i++) {
+ name += message[i];
+ }
+ address = name;
+ } else {
+ setState(() {
+ _msgs.addAll(message.split('\n'));
+ });
+ // print("_msgs: $_msgs");
+ }
+ },
+ onDone: () {
+ print('Server disconnected.');
+ toast('Server disconnected', 1);
+ _socket.destroy();
+ },
+ onError: (error) {
+ print('Error: $error');
+ toast('Error: $error', 1);
+ _socket.destroy();
+ },
+ );
+ } catch (e) {
+ print('Error: $e');
+ toast('An unexpected error occurred: $e', 1);
+ }
+ }
+
+ void _send() {
+ final value = _inputController.text;
+ if (value.isNotEmpty) {
+ _socket.write('$value\n');
+ _inputController.clear();
+ }
+ }
+
+ void toast(String msg, int type) {
+ Color bg = Color(0x7aa2f7ff);
+ Color fg = Colors.black;
+ switch (type) {
+ case 0:
+ bg = Colors.green;
+ break;
+ case 1:
+ bg = Colors.red;
+ break;
+ }
+ ScaffoldMessenger.of(context).showSnackBar(SnackBar(
+ content: Text(msg, style: TextStyle(color: fg)),
+ backgroundColor: bg,
+ ));
+ }
+}
+
+class BubbleReceive extends StatelessWidget {
+ final String message;
+ final String user;
+ const BubbleReceive({super.key, required this.message, required this.user});
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ mainAxisAlignment: MainAxisAlignment.end,
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ Flexible(
+ child: Container(
+ padding: EdgeInsets.all(15),
+ decoration: BoxDecoration(
+ color: Colors.blueGrey,
+ borderRadius: BorderRadius.circular(15),
+ ),
+ child: Text(
+ message,
+ style: const TextStyle(color: Colors.white, fontSize: 15),
+ ),
+ ),
+ ),
+ SizedBox(
+ width: 20,
+ height: 20,
+ child: CustomPaint(painter: Triangle(false, Colors.blueGrey)),
+ ),
+ ],
+ ),
+ Text(user),
+ SizedBox(height: 10),
+ ]);
+ }
+}
+
+class BubbleSend extends StatelessWidget {
+ final String message;
+ final String user;
+ const BubbleSend({super.key, required this.message, required this.user});
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ SizedBox(
+ width: 20,
+ height: 20,
+ child: CustomPaint(painter: Triangle(true, Colors.indigo)),
+ ),
+ Container(
+ padding: EdgeInsets.all(15),
+ decoration: BoxDecoration(
+ color: Colors.indigo,
+ borderRadius: BorderRadius.circular(15),
+ ),
+ child: Text(
+ message,
+ style: const TextStyle(color: Colors.white, fontSize: 15),
+ ),
+ ),
+ ],
+ ),
+ Text(user),
+ SizedBox(height: 10),
+ ]);
+ }
+}
+
+class Triangle extends CustomPainter {
+ final Color backgroundColor;
+ final bool send;
+ Triangle(this.send, this.backgroundColor);
+
+ @override
+ void paint(Canvas canvas, Size size) {
+ var paint = Paint()..color = backgroundColor;
+
+ var path = Path();
+ if (send) {
+ path.moveTo(20, 0);
+ path.lineTo(5, 15);
+ path.lineTo(35, 15);
+ } else {
+ path.lineTo(15, 15);
+ path.lineTo(-15, 15);
+ }
+ path.close();
+ canvas.drawPath(path, paint);
+ }
+
+ @override
+ bool shouldRepaint(CustomPainter oldDelegate) {
+ return false;
+ }
+}