Merge branch 'master' into feature/notifications
This commit is contained in:
@@ -1,3 +1,15 @@
|
||||
## 0.1.17
|
||||
|
||||
- Add dark theme
|
||||
|
||||
## 0.1.16
|
||||
|
||||
- Add possibility to show the other users username next to the message timestamp
|
||||
|
||||
## 0.1.15
|
||||
|
||||
- Fix MessageInput overflow
|
||||
|
||||
## 0.1.14
|
||||
|
||||
- Add automatic keep alive to streamchat
|
||||
|
||||
@@ -30,7 +30,7 @@ The example is available under the [example](https://github.com/GetStream/stream
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
stream_chat_flutter: ^0.1.13
|
||||
stream_chat_flutter: ^0.1.15
|
||||
```
|
||||
|
||||
You should then run `flutter packages get`
|
||||
|
||||
@@ -49,6 +49,9 @@ class MyApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
theme: ThemeData.light(),
|
||||
darkTheme: ThemeData.dark(),
|
||||
themeMode: ThemeMode.system,
|
||||
home: Container(
|
||||
child: StreamChat(
|
||||
client: client,
|
||||
|
||||
@@ -136,12 +136,16 @@ class ChannelHeader extends StatelessWidget implements PreferredSizeWidget {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
fillColor: Colors.black.withOpacity(.1),
|
||||
fillColor: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white.withOpacity(.1)
|
||||
: Colors.black.withOpacity(.1),
|
||||
padding: EdgeInsets.all(4),
|
||||
child: Icon(
|
||||
Icons.arrow_back_ios,
|
||||
size: 15,
|
||||
color: Colors.black,
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white
|
||||
: Colors.black,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -315,7 +315,9 @@ class _ChannelListViewState extends State<ChannelListView>
|
||||
Widget _separatorBuilder(context, i) {
|
||||
return Container(
|
||||
height: 1,
|
||||
color: Colors.black.withOpacity(0.1),
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white.withOpacity(0.1)
|
||||
: Colors.black.withOpacity(0.1),
|
||||
margin: EdgeInsets.symmetric(horizontal: 16),
|
||||
);
|
||||
}
|
||||
|
||||
+69
-53
@@ -56,12 +56,13 @@ import 'stream_channel.dart';
|
||||
/// The widget renders the ui based on the first ancestor of type [StreamChatTheme].
|
||||
/// Modify it to change the widget appearance.
|
||||
class MessageInput extends StatefulWidget {
|
||||
MessageInput({
|
||||
Key key,
|
||||
this.onMessageSent,
|
||||
this.parentMessage,
|
||||
this.editMessage,
|
||||
}) : super(key: key);
|
||||
MessageInput(
|
||||
{Key key,
|
||||
this.onMessageSent,
|
||||
this.parentMessage,
|
||||
this.editMessage,
|
||||
this.maxHeight = 150})
|
||||
: super(key: key);
|
||||
|
||||
/// Message to edit
|
||||
final Message editMessage;
|
||||
@@ -72,6 +73,9 @@ class MessageInput extends StatefulWidget {
|
||||
/// Parent message in case of a thread
|
||||
final Message parentMessage;
|
||||
|
||||
/// Maximum Height for the TextField to grow before it starts scrolling
|
||||
final double maxHeight;
|
||||
|
||||
@override
|
||||
_MessageInputState createState() => _MessageInputState();
|
||||
}
|
||||
@@ -111,6 +115,7 @@ class _MessageInputState extends State<MessageInput> {
|
||||
Flex _buildTextField(BuildContext context) {
|
||||
return Flex(
|
||||
direction: Axis.horizontal,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
_buildAttachmentButton(),
|
||||
_buildTextInput(context),
|
||||
@@ -133,54 +138,57 @@ class _MessageInputState extends State<MessageInput> {
|
||||
|
||||
Expanded _buildTextInput(BuildContext context) {
|
||||
return Expanded(
|
||||
child: TextField(
|
||||
key: Key('messageInputText'),
|
||||
minLines: null,
|
||||
maxLines: null,
|
||||
onSubmitted: (_) {
|
||||
_sendMessage(context);
|
||||
},
|
||||
controller: _textController,
|
||||
focusNode: _focusNode,
|
||||
onChanged: (s) {
|
||||
StreamChannel.of(context).channel.keyStroke();
|
||||
child: LimitedBox(
|
||||
maxHeight: widget.maxHeight,
|
||||
child: TextField(
|
||||
key: Key('messageInputText'),
|
||||
minLines: null,
|
||||
maxLines: null,
|
||||
onSubmitted: (_) {
|
||||
_sendMessage(context);
|
||||
},
|
||||
controller: _textController,
|
||||
focusNode: _focusNode,
|
||||
onChanged: (s) {
|
||||
StreamChannel.of(context).channel.keyStroke();
|
||||
|
||||
setState(() {
|
||||
_messageIsPresent = s.trim().isNotEmpty;
|
||||
});
|
||||
setState(() {
|
||||
_messageIsPresent = s.trim().isNotEmpty;
|
||||
});
|
||||
|
||||
_commandsOverlay?.remove();
|
||||
_commandsOverlay = null;
|
||||
_mentionsOverlay?.remove();
|
||||
_mentionsOverlay = null;
|
||||
_commandsOverlay?.remove();
|
||||
_commandsOverlay = null;
|
||||
_mentionsOverlay?.remove();
|
||||
_mentionsOverlay = null;
|
||||
|
||||
if (s.startsWith('/')) {
|
||||
_commandsOverlay = _buildCommandsOverlayEntry();
|
||||
Overlay.of(context).insert(_commandsOverlay);
|
||||
}
|
||||
if (s.startsWith('/')) {
|
||||
_commandsOverlay = _buildCommandsOverlayEntry();
|
||||
Overlay.of(context).insert(_commandsOverlay);
|
||||
}
|
||||
|
||||
if (_textController.selection.isCollapsed &&
|
||||
(s[_textController.selection.start - 1] == '@' ||
|
||||
_textController.text
|
||||
.substring(0, _textController.selection.start)
|
||||
.split(' ')
|
||||
.last
|
||||
.contains('@'))) {
|
||||
_mentionsOverlay = _buildMentionsOverlayEntry();
|
||||
Overlay.of(context).insert(_mentionsOverlay);
|
||||
}
|
||||
},
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_typingStarted = true;
|
||||
});
|
||||
},
|
||||
style: Theme.of(context).textTheme.body1,
|
||||
autofocus: false,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Write a message',
|
||||
prefixText: ' ',
|
||||
border: InputBorder.none,
|
||||
if (_textController.selection.isCollapsed &&
|
||||
(s[_textController.selection.start - 1] == '@' ||
|
||||
_textController.text
|
||||
.substring(0, _textController.selection.start)
|
||||
.split(' ')
|
||||
.last
|
||||
.contains('@'))) {
|
||||
_mentionsOverlay = _buildMentionsOverlayEntry();
|
||||
Overlay.of(context).insert(_mentionsOverlay);
|
||||
}
|
||||
},
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_typingStarted = true;
|
||||
});
|
||||
},
|
||||
style: Theme.of(context).textTheme.body1,
|
||||
autofocus: false,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Write a message',
|
||||
prefixText: ' ',
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -197,7 +205,10 @@ class _MessageInputState extends State<MessageInput> {
|
||||
),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: StreamChatTheme.of(context)
|
||||
.channelTheme
|
||||
.inputBackground
|
||||
.withAlpha(255),
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
child: Container(
|
||||
@@ -207,7 +218,9 @@ class _MessageInputState extends State<MessageInput> {
|
||||
border: Border.all(
|
||||
color: _typingStarted
|
||||
? Colors.transparent
|
||||
: Colors.black.withOpacity(.2)),
|
||||
: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white.withOpacity(.2)
|
||||
: Colors.black.withOpacity(.2)),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -775,7 +788,10 @@ class _MessageInputState extends State<MessageInput> {
|
||||
if (attachment.type == 'image') {
|
||||
_attachments.add(_SendingAttachment(
|
||||
type: FileType.image,
|
||||
url: attachment.imageUrl,
|
||||
url: attachment.imageUrl ??
|
||||
attachment.assetUrl ??
|
||||
attachment.thumbUrl ??
|
||||
attachment.ogScrapeUrl,
|
||||
uploaded: true,
|
||||
));
|
||||
} else if (attachment.type == 'video') {
|
||||
|
||||
@@ -61,6 +61,7 @@ class MessageListView extends StatefulWidget {
|
||||
this.parentMessage,
|
||||
this.threadBuilder,
|
||||
this.onThreadTap,
|
||||
this.showOtherMessageUsername = false,
|
||||
}) : super(key: key);
|
||||
|
||||
/// Function used to build a custom message widget
|
||||
@@ -79,6 +80,9 @@ class MessageListView extends StatefulWidget {
|
||||
/// Parent message in case of a thread
|
||||
final Message parentMessage;
|
||||
|
||||
/// If true show the other users username next to the timestamp of the message
|
||||
final bool showOtherMessageUsername;
|
||||
|
||||
@override
|
||||
_MessageListViewState createState() => _MessageListViewState();
|
||||
}
|
||||
@@ -142,7 +146,7 @@ class _MessageListViewState extends State<MessageListView> {
|
||||
'Start of thread',
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
color: Theme.of(context).primaryColorLight,
|
||||
color: Theme.of(context).accentColor.withAlpha(50),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -193,6 +197,7 @@ class _MessageListViewState extends State<MessageListView> {
|
||||
message: message,
|
||||
nextMessage: nextMessage,
|
||||
onThreadTap: _onThreadTap,
|
||||
showOtherMessageUsername: widget.showOtherMessageUsername,
|
||||
);
|
||||
},
|
||||
childCount: _messages.length + 2,
|
||||
|
||||
+114
-22
@@ -41,6 +41,7 @@ class MessageWidget extends StatefulWidget {
|
||||
this.onMessageActions,
|
||||
this.isParent = false,
|
||||
this.onMentionTap,
|
||||
this.showOtherMessageUsername = false,
|
||||
}) : super(key: key);
|
||||
|
||||
/// Function called on mention tap
|
||||
@@ -49,6 +50,9 @@ class MessageWidget extends StatefulWidget {
|
||||
/// Function called on long press
|
||||
final Function(BuildContext, Message) onMessageActions;
|
||||
|
||||
/// If true show the other users username next to the timestamp of the message
|
||||
final bool showOtherMessageUsername;
|
||||
|
||||
/// This message
|
||||
final Message message;
|
||||
|
||||
@@ -161,6 +165,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
backgroundColor: StreamChatTheme.of(context).accentColor,
|
||||
child: Icon(
|
||||
Icons.done,
|
||||
color: Colors.white,
|
||||
size: 4,
|
||||
),
|
||||
),
|
||||
@@ -192,7 +197,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
),
|
||||
child: CircleAvatar(
|
||||
radius: 4,
|
||||
backgroundColor: Color(0xffd0021B).withAlpha(125),
|
||||
backgroundColor: Color(0xffd0021B).withOpacity(.1),
|
||||
child: Icon(
|
||||
Icons.error_outline,
|
||||
size: 4,
|
||||
@@ -234,7 +239,9 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
'This message was deleted...',
|
||||
style: _messageTheme.messageText.copyWith(
|
||||
fontStyle: FontStyle.italic,
|
||||
color: Colors.black,
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white
|
||||
: Colors.black,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -252,7 +259,9 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
alignment: Alignment.center,
|
||||
child: Icon(
|
||||
Icons.subdirectory_arrow_left,
|
||||
color: Colors.black12,
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white12
|
||||
: Colors.black12,
|
||||
),
|
||||
),
|
||||
];
|
||||
@@ -422,9 +431,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
int nOfAttachmentWidgets,
|
||||
BuildContext context,
|
||||
) {
|
||||
final boxDecoration = _buildBoxDecoration(_isLastUser).copyWith(
|
||||
color: Color(0xffebebeb),
|
||||
);
|
||||
final boxDecoration = _buildBoxDecoration(_isLastUser);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 2.0),
|
||||
child: Column(
|
||||
@@ -435,7 +442,8 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
child: Container(
|
||||
decoration: boxDecoration,
|
||||
constraints: BoxConstraints.loose(
|
||||
Size.fromWidth(MediaQuery.of(context).size.width * 0.7)),
|
||||
Size.fromWidth(MediaQuery.of(context).size.width * 0.7),
|
||||
),
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
Column(
|
||||
@@ -513,6 +521,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
_buildBoxDecoration(_isLastUser || nOfAttachmentWidgets > 0),
|
||||
padding: EdgeInsets.all(10),
|
||||
constraints: BoxConstraints.loose(
|
||||
<<<<<<< HEAD
|
||||
Size.fromWidth(MediaQuery.of(context).size.width * 0.7),
|
||||
),
|
||||
child: _buildSendingError(
|
||||
@@ -527,6 +536,38 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
|
||||
if (widget.onMentionTap != null) {
|
||||
widget.onMentionTap(mentionedUser);
|
||||
=======
|
||||
Size.fromWidth(MediaQuery.of(context).size.width * 0.7)),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
if (widget.message.status == MessageSendingStatus.FAILED)
|
||||
Text(
|
||||
'MESSAGE FAILED · CLICK TO TRY AGAIN',
|
||||
style: _messageTheme.messageText.copyWith(
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white.withOpacity(.5)
|
||||
: Colors.black.withOpacity(.5),
|
||||
fontSize: 11,
|
||||
),
|
||||
),
|
||||
MarkdownBody(
|
||||
data: text,
|
||||
onTapLink: (link) {
|
||||
if (link.startsWith('@')) {
|
||||
final mentionedUser =
|
||||
widget.message.mentionedUsers.firstWhere(
|
||||
(u) => '@${u.name.replaceAll(' ', '')}' == link,
|
||||
orElse: () => null,
|
||||
);
|
||||
|
||||
if (widget.onMentionTap != null) {
|
||||
widget.onMentionTap(mentionedUser);
|
||||
} else {
|
||||
print('tap on ${mentionedUser.name}');
|
||||
}
|
||||
>>>>>>> master
|
||||
} else {
|
||||
print('tap on ${mentionedUser.name}');
|
||||
}
|
||||
@@ -662,7 +703,6 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
],
|
||||
),
|
||||
),
|
||||
color: Color(0xffebebeb),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -674,7 +714,11 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
right: !_isMyMessage ? 8 : null,
|
||||
top: -6,
|
||||
child: CustomPaint(
|
||||
painter: _ReactionBubblePainter(),
|
||||
painter: _ReactionBubblePainter(
|
||||
Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white
|
||||
: Colors.black,
|
||||
),
|
||||
),
|
||||
)
|
||||
: SizedBox();
|
||||
@@ -823,12 +867,18 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
fillColor: Colors.black.withOpacity(.1),
|
||||
fillColor:
|
||||
Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white.withOpacity(.1)
|
||||
: Colors.black.withOpacity(.1),
|
||||
padding: EdgeInsets.all(4),
|
||||
child: Icon(
|
||||
Icons.close,
|
||||
size: 15,
|
||||
color: Colors.black,
|
||||
color:
|
||||
Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white
|
||||
: Colors.black,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -881,7 +931,9 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
? const EdgeInsets.all(8)
|
||||
: EdgeInsets.zero,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black,
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white
|
||||
: Colors.black,
|
||||
borderRadius: BorderRadius.all(Radius.circular(14))),
|
||||
child: AnimatedSwitcher(
|
||||
duration: Duration(milliseconds: 300),
|
||||
@@ -912,7 +964,11 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
widget.message.reactionCounts.values
|
||||
.fold(0, (t, v) => v + t)
|
||||
.toString(),
|
||||
style: TextStyle(color: Colors.white),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.black
|
||||
: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -931,6 +987,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
Widget _buildImage(
|
||||
Attachment attachment,
|
||||
) {
|
||||
<<<<<<< HEAD
|
||||
return Hero(
|
||||
tag: attachment.imageUrl ?? attachment.assetUrl ?? attachment.thumbUrl,
|
||||
child: CachedNetworkImage(
|
||||
@@ -958,6 +1015,17 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
attachment.thumbUrl ?? attachment.imageUrl ?? attachment.assetUrl,
|
||||
errorWidget: (context, url, error) => _buildErrorImage(attachment),
|
||||
fit: BoxFit.cover,
|
||||
=======
|
||||
final errorWidget = Container(
|
||||
width: 200,
|
||||
height: 140,
|
||||
color: Color(0xffd0021B).withOpacity(.1),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.error_outline,
|
||||
color: Colors.white,
|
||||
),
|
||||
>>>>>>> master
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -1059,29 +1127,49 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
Widget _buildTimestamp(Alignment alignment) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 5.0),
|
||||
child: widget.message.createdAt != null
|
||||
? Text(
|
||||
Jiffy(widget.message.createdAt.toLocal()).format('HH:mm'),
|
||||
style: _messageTheme.createdAt,
|
||||
)
|
||||
: SizedBox(),
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
style: _messageTheme.createdAt,
|
||||
children: <TextSpan>[
|
||||
if (!_isMyMessage && widget.showOtherMessageUsername)
|
||||
TextSpan(
|
||||
text: widget.message.user.name,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
if (widget.message.createdAt != null)
|
||||
TextSpan(
|
||||
text:
|
||||
Jiffy(widget.message.createdAt.toLocal()).format(' HH:mm'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
BoxDecoration _buildBoxDecoration(bool rectBorders) {
|
||||
return BoxDecoration(
|
||||
border:
|
||||
_isMyMessage ? null : Border.all(color: Colors.black.withAlpha(8)),
|
||||
border: _isMyMessage
|
||||
? null
|
||||
: Border.all(
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white.withAlpha(24)
|
||||
: Colors.black.withAlpha(24)),
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular((_isMyMessage || !rectBorders) ? 16 : 2),
|
||||
bottomLeft: Radius.circular(_isMyMessage ? 16 : 2),
|
||||
topRight: Radius.circular((_isMyMessage && rectBorders) ? 2 : 16),
|
||||
bottomRight: Radius.circular(_isMyMessage ? 2 : 16),
|
||||
),
|
||||
<<<<<<< HEAD
|
||||
color: (widget.message.status == MessageSendingStatus.FAILED ||
|
||||
widget.message.status == MessageSendingStatus.FAILED_UPDATE ||
|
||||
widget.message.status == MessageSendingStatus.FAILED_DELETE)
|
||||
? Color(0xffd0021B).withAlpha(26)
|
||||
=======
|
||||
color: widget.message.status == MessageSendingStatus.FAILED
|
||||
? Color(0xffd0021B).withOpacity(.1)
|
||||
>>>>>>> master
|
||||
: _messageTheme.messageBackgroundColor,
|
||||
);
|
||||
}
|
||||
@@ -1093,9 +1181,13 @@ class _MessageWidgetState extends State<MessageWidget>
|
||||
}
|
||||
|
||||
class _ReactionBubblePainter extends CustomPainter {
|
||||
final Color color;
|
||||
|
||||
_ReactionBubblePainter(this.color);
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint = Paint()..color = Colors.black;
|
||||
final paint = Paint()..color = color;
|
||||
final path = Path();
|
||||
path.arcToPoint(Offset(-6, -6));
|
||||
path.arcToPoint(Offset(0, 10));
|
||||
|
||||
+30
-26
@@ -68,33 +68,37 @@ class StreamChatState extends State<StreamChat> with WidgetsBindingObserver {
|
||||
return StreamChatTheme(
|
||||
data: theme,
|
||||
child: Builder(
|
||||
builder: (context) => Theme(
|
||||
data: Theme.of(context).copyWith(
|
||||
accentColor: StreamChatTheme.of(context).accentColor,
|
||||
scaffoldBackgroundColor: Colors.white,
|
||||
backgroundColor: Colors.white,
|
||||
),
|
||||
child: WillPopScope(
|
||||
onWillPop: () async {
|
||||
if (_navigatorKey.currentState.canPop()) {
|
||||
_navigatorKey.currentState.pop();
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
child: Navigator(
|
||||
initialRoute: '/',
|
||||
key: _navigatorKey,
|
||||
onGenerateRoute: (settings) {
|
||||
return MaterialPageRoute(
|
||||
settings: settings,
|
||||
builder: (_) => widget.child,
|
||||
);
|
||||
},
|
||||
builder: (context) {
|
||||
final materialTheme = Theme.of(context);
|
||||
final isDark = materialTheme.brightness == Brightness.dark;
|
||||
return Theme(
|
||||
data: materialTheme.copyWith(
|
||||
accentColor: StreamChatTheme.of(context).accentColor,
|
||||
scaffoldBackgroundColor: isDark ? Colors.black : Colors.white,
|
||||
backgroundColor: isDark ? Colors.black : Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: WillPopScope(
|
||||
onWillPop: () async {
|
||||
if (_navigatorKey.currentState.canPop()) {
|
||||
_navigatorKey.currentState.pop();
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
child: Navigator(
|
||||
initialRoute: '/',
|
||||
key: _navigatorKey,
|
||||
onGenerateRoute: (settings) {
|
||||
return MaterialPageRoute(
|
||||
settings: settings,
|
||||
builder: (_) => widget.child,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -166,9 +166,10 @@ class StreamChatThemeData {
|
||||
/// Get the default Stream Chat theme
|
||||
static StreamChatThemeData getDefaultTheme(ThemeData theme) {
|
||||
final accentColor = Color(0xff006cff);
|
||||
final isDark = theme.brightness == Brightness.dark;
|
||||
return StreamChatThemeData(
|
||||
accentColor: accentColor,
|
||||
primaryColor: Colors.white,
|
||||
primaryColor: isDark ? Colors.black : Colors.white,
|
||||
channelPreviewTheme: ChannelPreviewTheme(
|
||||
avatarTheme: AvatarTheme(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
@@ -179,15 +180,17 @@ class StreamChatThemeData {
|
||||
),
|
||||
title: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.black,
|
||||
color: isDark ? Colors.white : Colors.black,
|
||||
),
|
||||
subtitle: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.black,
|
||||
color: isDark ? Colors.white : Colors.black,
|
||||
),
|
||||
lastMessageAt: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Colors.black.withOpacity(.5),
|
||||
color: isDark
|
||||
? Colors.white.withOpacity(.5)
|
||||
: Colors.black.withOpacity(.5),
|
||||
),
|
||||
),
|
||||
channelTheme: ChannelTheme(
|
||||
@@ -202,17 +205,20 @@ class StreamChatThemeData {
|
||||
width: 40,
|
||||
),
|
||||
),
|
||||
color: Colors.white,
|
||||
color: isDark ? Colors.black : Colors.white,
|
||||
title: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.black,
|
||||
color: isDark ? Colors.white : Colors.black,
|
||||
),
|
||||
lastMessageAt: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Colors.black.withOpacity(.5),
|
||||
color: isDark
|
||||
? Colors.white.withOpacity(.5)
|
||||
: Colors.black.withOpacity(.5),
|
||||
),
|
||||
),
|
||||
inputBackground: Colors.black.withAlpha(12),
|
||||
inputBackground:
|
||||
isDark ? Colors.black.withAlpha(12) : Colors.white.withAlpha(12),
|
||||
inputGradient: LinearGradient(colors: [
|
||||
Color(0xFF00AEFF),
|
||||
Color(0xFF0076FF),
|
||||
@@ -221,10 +227,12 @@ class StreamChatThemeData {
|
||||
ownMessageTheme: MessageTheme(
|
||||
messageText: TextStyle(
|
||||
fontSize: 15,
|
||||
color: Colors.black,
|
||||
color: isDark ? Colors.white : Colors.black,
|
||||
),
|
||||
createdAt: TextStyle(
|
||||
color: Colors.black.withOpacity(.5),
|
||||
color: isDark
|
||||
? Colors.white.withOpacity(.5)
|
||||
: Colors.black.withOpacity(.5),
|
||||
fontSize: 11,
|
||||
),
|
||||
replies: TextStyle(
|
||||
@@ -232,7 +240,7 @@ class StreamChatThemeData {
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
messageBackgroundColor: Color(0xffebebeb),
|
||||
messageBackgroundColor: Color(0x33ebebeb),
|
||||
avatarTheme: AvatarTheme(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
constraints: BoxConstraints.tightFor(
|
||||
@@ -244,10 +252,12 @@ class StreamChatThemeData {
|
||||
otherMessageTheme: MessageTheme(
|
||||
messageText: TextStyle(
|
||||
fontSize: 15,
|
||||
color: Colors.black,
|
||||
color: isDark ? Colors.white : Colors.black,
|
||||
),
|
||||
createdAt: TextStyle(
|
||||
color: Colors.black.withOpacity(.5),
|
||||
color: isDark
|
||||
? Colors.white.withOpacity(.5)
|
||||
: Colors.black.withOpacity(.5),
|
||||
fontSize: 11,
|
||||
),
|
||||
replies: TextStyle(
|
||||
@@ -255,7 +265,7 @@ class StreamChatThemeData {
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
messageBackgroundColor: Colors.white,
|
||||
messageBackgroundColor: isDark ? Colors.black : Colors.white,
|
||||
avatarTheme: AvatarTheme(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
constraints: BoxConstraints.tightFor(
|
||||
|
||||
@@ -122,12 +122,16 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
fillColor: Colors.black.withOpacity(.1),
|
||||
fillColor: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white.withOpacity(.1)
|
||||
: Colors.black.withOpacity(.1),
|
||||
padding: EdgeInsets.all(4),
|
||||
child: Icon(
|
||||
Icons.close,
|
||||
size: 15,
|
||||
color: Colors.black,
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white
|
||||
: Colors.black,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
name: stream_chat_flutter
|
||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||
description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter.
|
||||
version: 0.1.14
|
||||
version: 0.1.17
|
||||
|
||||
environment:
|
||||
sdk: ">=2.3.0 <3.0.0"
|
||||
|
||||
Reference in New Issue
Block a user