Encrypted messaging app
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
4.3 KiB

  1. import 'package:Envelope/components/view_image.dart';
  2. import 'package:Envelope/models/image_message.dart';
  3. import 'package:Envelope/models/my_profile.dart';
  4. import 'package:Envelope/utils/time.dart';
  5. import 'package:flutter/material.dart';
  6. import '/models/messages.dart';
  7. @immutable
  8. class ConversationMessage extends StatelessWidget {
  9. const ConversationMessage({
  10. Key? key,
  11. required this.message,
  12. required this.profile,
  13. required this.index,
  14. }) : super(key: key);
  15. final Message message;
  16. final MyProfile profile;
  17. final int index;
  18. @override
  19. Widget build(BuildContext context) {
  20. return Container(
  21. padding: const EdgeInsets.only(left: 14,right: 14,top: 0,bottom: 0),
  22. child: Align(
  23. alignment: (
  24. message.senderUsername == profile.username ?
  25. Alignment.topRight :
  26. Alignment.topLeft
  27. ),
  28. child: Column(
  29. crossAxisAlignment: message.senderUsername == profile.username ?
  30. CrossAxisAlignment.end :
  31. CrossAxisAlignment.start,
  32. children: <Widget>[
  33. messageContent(context),
  34. const SizedBox(height: 1.5),
  35. Row(
  36. mainAxisAlignment: message.senderUsername == profile.username ?
  37. MainAxisAlignment.end :
  38. MainAxisAlignment.start,
  39. children: <Widget>[
  40. const SizedBox(width: 10),
  41. usernameOrFailedToSend(index),
  42. ],
  43. ),
  44. const SizedBox(height: 1.5),
  45. Row(
  46. mainAxisAlignment: message.senderUsername == profile.username ?
  47. MainAxisAlignment.end :
  48. MainAxisAlignment.start,
  49. children: <Widget>[
  50. const SizedBox(width: 10),
  51. Text(
  52. convertToAgo(message.createdAt),
  53. textAlign: message.senderUsername == profile.username ?
  54. TextAlign.left :
  55. TextAlign.right,
  56. style: TextStyle(
  57. fontSize: 12,
  58. color: Colors.grey[500],
  59. ),
  60. ),
  61. ],
  62. ),
  63. index != 0 ?
  64. const SizedBox(height: 20) :
  65. const SizedBox.shrink(),
  66. ],
  67. )
  68. ),
  69. );
  70. }
  71. Widget messageContent(BuildContext context) {
  72. if (message.runtimeType == ImageMessage) {
  73. return GestureDetector(
  74. onTap: () {
  75. Navigator.push(context, MaterialPageRoute(builder: (context) {
  76. return ViewImage(
  77. message: (message as ImageMessage)
  78. );
  79. }));
  80. },
  81. child: ConstrainedBox(
  82. constraints: const BoxConstraints(maxHeight: 350, maxWidth: 250),
  83. child: ClipRRect(
  84. borderRadius: BorderRadius.circular(20),
  85. child: Image.file(
  86. (message as ImageMessage).file,
  87. fit: BoxFit.fill,
  88. ),
  89. ),
  90. ),
  91. );
  92. }
  93. return Container(
  94. decoration: BoxDecoration(
  95. borderRadius: BorderRadius.circular(20),
  96. color: (
  97. message.senderUsername == profile.username ?
  98. Theme.of(context).colorScheme.primary :
  99. Theme.of(context).colorScheme.tertiary
  100. ),
  101. ),
  102. padding: const EdgeInsets.all(12),
  103. child: Text(
  104. message.getContent(),
  105. style: TextStyle(
  106. fontSize: 15,
  107. color: message.senderUsername == profile.username ?
  108. Theme.of(context).colorScheme.onPrimary :
  109. Theme.of(context).colorScheme.onTertiary,
  110. ),
  111. ),
  112. );
  113. }
  114. Widget usernameOrFailedToSend(int index) {
  115. if (message.senderUsername != profile.username) {
  116. return Text(
  117. message.senderUsername,
  118. style: TextStyle(
  119. fontSize: 12,
  120. color: Colors.grey[300],
  121. ),
  122. );
  123. }
  124. if (message.failedToSend) {
  125. return Row(
  126. mainAxisAlignment: MainAxisAlignment.end,
  127. children: const <Widget>[
  128. Icon(
  129. Icons.warning_rounded,
  130. color: Colors.red,
  131. size: 20,
  132. ),
  133. Text(
  134. 'Failed to send',
  135. style: TextStyle(color: Colors.red, fontSize: 12),
  136. textAlign: TextAlign.right,
  137. ),
  138. ],
  139. );
  140. }
  141. return const SizedBox.shrink();
  142. }
  143. }