Created
January 21, 2023 06:23
-
-
Save SuperPenguin/4467ad51f6ff145ac6b199bfe82a98aa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:boxy/boxy.dart'; | |
import 'package:flutter/material.dart'; | |
void main() { | |
runApp(const App()); | |
} | |
class App extends StatelessWidget { | |
const App({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return const MaterialApp( | |
debugShowCheckedModeBanner: false, | |
home: HomeScreen(), | |
); | |
} | |
} | |
class HomeScreen extends StatefulWidget { | |
const HomeScreen({super.key}); | |
@override | |
State<HomeScreen> createState() => _HomeScreenState(); | |
} | |
class _HomeScreenState extends State<HomeScreen> { | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: const Text('Chat'), | |
), | |
body: ListView.builder( | |
reverse: true, | |
itemCount: chats.length, | |
itemBuilder: (context, index) { | |
final c = chats[index]; | |
return Row( | |
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |
children: [ | |
if (c.side == ChatSide.right) const SizedBox(width: 24.0), | |
Flexible(child: ChatBubble(chat: c)), | |
if (c.side == ChatSide.left) const SizedBox(width: 24.0), | |
], | |
); | |
}, | |
), | |
); | |
} | |
} | |
class ChatBubble extends StatelessWidget { | |
const ChatBubble({ | |
super.key, | |
required this.chat, | |
}); | |
final Chat chat; | |
@override | |
Widget build(BuildContext context) { | |
final theme = Theme.of(context); | |
return Card( | |
color: chat.side.color, | |
child: Padding( | |
padding: const EdgeInsets.all(8.0), | |
child: CustomBoxy( | |
delegate: _Delegate( | |
chat: chat, | |
messageStyle: theme.textTheme.bodyMedium, | |
timeStyle: theme.textTheme.bodySmall, | |
), | |
), | |
), | |
); | |
} | |
} | |
class _Delegate extends BoxyDelegate { | |
_Delegate({ | |
required this.chat, | |
required this.messageStyle, | |
required this.timeStyle, | |
}); | |
final Chat chat; | |
final TextStyle? messageStyle; | |
final TextStyle? timeStyle; | |
@override | |
Size layout() { | |
final hour = chat.time.hour.toString().padLeft(2, '0'); | |
final minute = chat.time.minute.toString().padLeft(2, '0'); | |
final timeText = Text( | |
'$hour:$minute', | |
style: timeStyle, | |
); | |
final timeChild = inflate(timeText); | |
final timeSize = timeChild.layout(constraints); | |
final messageText = Text.rich( | |
TextSpan( | |
text: '${chat.message} ', | |
children: [ | |
WidgetSpan( | |
child: SizedBox( | |
width: timeSize.width, | |
height: timeSize.height, | |
), | |
alignment: PlaceholderAlignment.bottom, | |
), | |
], | |
), | |
style: messageStyle, | |
); | |
final messageChild = inflate(messageText); | |
final messageSize = messageChild.layout(constraints); | |
messageChild.position(Offset.zero); | |
timeChild.position( | |
Offset( | |
messageSize.width - timeSize.width, | |
messageSize.height - timeSize.height, | |
), | |
); | |
return messageSize; | |
} | |
} | |
enum ChatSide { | |
left(color: Color(0xFFD6D6D6)), | |
right(color: Color(0xFFA5D6A7)); | |
const ChatSide({ | |
required this.color, | |
}); | |
final Color color; | |
} | |
@immutable | |
class Chat { | |
const Chat({ | |
required this.side, | |
required this.time, | |
required this.message, | |
}); | |
final ChatSide side; | |
final DateTime time; | |
final String message; | |
} | |
final List<Chat> chats = [ | |
Chat( | |
side: ChatSide.left, | |
time: DateTime(2023, 01, 21, 9, 9), | |
message: | |
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', | |
), | |
Chat( | |
side: ChatSide.right, | |
time: DateTime(2023, 01, 21, 9, 8), | |
message: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', | |
), | |
Chat( | |
side: ChatSide.left, | |
time: DateTime(2023, 01, 21, 9, 7), | |
message: | |
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', | |
), | |
Chat( | |
side: ChatSide.right, | |
time: DateTime(2023, 01, 21, 9, 6), | |
message: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', | |
), | |
Chat( | |
side: ChatSide.left, | |
time: DateTime(2023, 01, 21, 9, 5), | |
message: | |
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', | |
), | |
Chat( | |
side: ChatSide.right, | |
time: DateTime(2023, 01, 21, 9, 4), | |
message: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', | |
), | |
Chat( | |
side: ChatSide.left, | |
time: DateTime(2023, 01, 21, 9, 3), | |
message: | |
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', | |
), | |
Chat( | |
side: ChatSide.right, | |
time: DateTime(2023, 01, 21, 9, 2), | |
message: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', | |
), | |
Chat( | |
side: ChatSide.left, | |
time: DateTime(2023, 01, 21, 9, 1), | |
message: | |
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', | |
), | |
Chat( | |
side: ChatSide.right, | |
time: DateTime(2023, 01, 21, 9, 0), | |
message: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', | |
), | |
]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment