@@ -382,7 +382,7 @@ class _ChatInfoScreenState extends State<ChatInfoScreen> {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
constraints: BoxConstraints.tightFor(
|
||||
width: 28,
|
||||
width: 24,
|
||||
height: 12,
|
||||
),
|
||||
child: Material(
|
||||
@@ -393,6 +393,10 @@ class _ChatInfoScreenState extends State<ChatInfoScreen> {
|
||||
color: StreamChatTheme.of(context).colorTheme.white,
|
||||
),
|
||||
alternativeWidget,
|
||||
if (widget.user.online)
|
||||
SizedBox(
|
||||
width: 24.0,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -939,28 +939,7 @@ class _GroupInfoScreenState extends State<GroupInfoScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (user.online)
|
||||
Material(
|
||||
type: MaterialType.circle,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
constraints: BoxConstraints.tightFor(
|
||||
width: 28,
|
||||
height: 12,
|
||||
),
|
||||
child: Material(
|
||||
shape: CircleBorder(),
|
||||
color: Color(0xff20E070),
|
||||
),
|
||||
),
|
||||
color: StreamChatTheme.of(context).colorTheme.white,
|
||||
),
|
||||
alternativeWidget,
|
||||
],
|
||||
);
|
||||
return alternativeWidget;
|
||||
}
|
||||
|
||||
Widget _buildModalListTile(
|
||||
|
||||
@@ -10,6 +10,8 @@ import 'stream_channel.dart';
|
||||
|
||||
import '../stream_chat_flutter.dart';
|
||||
|
||||
enum ReturnActionType { none, reply }
|
||||
|
||||
typedef ShowMessageCallback = void Function(Message message, Channel channel);
|
||||
|
||||
/// A full screen image widget
|
||||
|
||||
@@ -13,6 +13,7 @@ class GiphyAttachment extends StatelessWidget {
|
||||
final Message message;
|
||||
final Size size;
|
||||
final ShowMessageCallback onShowMessage;
|
||||
final ValueChanged<ReturnActionType> onReturnAction;
|
||||
|
||||
const GiphyAttachment({
|
||||
Key key,
|
||||
@@ -21,6 +22,7 @@ class GiphyAttachment extends StatelessWidget {
|
||||
this.message,
|
||||
this.size,
|
||||
this.onShowMessage,
|
||||
this.onReturnAction,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@@ -65,23 +67,8 @@ class GiphyAttachment extends StatelessWidget {
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (_) {
|
||||
final channel = StreamChannel.of(context).channel;
|
||||
|
||||
return StreamChannel(
|
||||
channel: channel,
|
||||
child: FullScreenMedia(
|
||||
mediaAttachments: [
|
||||
attachment,
|
||||
],
|
||||
userName: message.user.name,
|
||||
sentAt: message.createdAt,
|
||||
message: message,
|
||||
onShowMessage: onShowMessage,
|
||||
),
|
||||
);
|
||||
}));
|
||||
onTap: () async {
|
||||
_onImageTap(context);
|
||||
},
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.only(
|
||||
@@ -317,11 +304,37 @@ class GiphyAttachment extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
void _onImageTap(BuildContext context) async {
|
||||
var res = await Navigator.push(context, MaterialPageRoute(
|
||||
builder: (_) {
|
||||
final channel = StreamChannel.of(context).channel;
|
||||
|
||||
return StreamChannel(
|
||||
channel: channel,
|
||||
child: FullScreenMedia(
|
||||
mediaAttachments: [
|
||||
attachment,
|
||||
],
|
||||
userName: message.user.name,
|
||||
sentAt: message.createdAt,
|
||||
message: message,
|
||||
onShowMessage: onShowMessage,
|
||||
),
|
||||
);
|
||||
},
|
||||
));
|
||||
|
||||
if (res != null) {
|
||||
onReturnAction(res);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildSentAttachment(context) {
|
||||
return Container(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (_) {
|
||||
onTap: () async {
|
||||
var res =
|
||||
await Navigator.push(context, MaterialPageRoute(builder: (_) {
|
||||
var channel = StreamChannel.of(context).channel;
|
||||
|
||||
return StreamChannel(
|
||||
@@ -337,6 +350,10 @@ class GiphyAttachment extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}));
|
||||
|
||||
if (res != null) {
|
||||
onReturnAction(res);
|
||||
}
|
||||
},
|
||||
child: Stack(
|
||||
children: [
|
||||
|
||||
@@ -60,7 +60,9 @@ class ImageActionsModal extends StatelessWidget {
|
||||
size: 24.0,
|
||||
color: StreamChatTheme.of(context).colorTheme.grey,
|
||||
),
|
||||
() {},
|
||||
() {
|
||||
Navigator.pop(context, ReturnActionType.reply);
|
||||
},
|
||||
),
|
||||
_buildButton(
|
||||
context,
|
||||
@@ -83,12 +85,12 @@ class ImageActionsModal extends StatelessWidget {
|
||||
urls[currentIndex].assetUrl ??
|
||||
urls[currentIndex].thumbUrl;
|
||||
|
||||
Navigator.pop(context);
|
||||
|
||||
if (urls[currentIndex].type == 'video') {
|
||||
await _saveVideo(url);
|
||||
Navigator.pop(context);
|
||||
} else {
|
||||
await _saveImage(url);
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
@@ -14,6 +14,7 @@ class ImageAttachment extends StatelessWidget {
|
||||
final Size size;
|
||||
final bool showTitle;
|
||||
final ShowMessageCallback onShowMessage;
|
||||
final ValueChanged<ReturnActionType> onReturnAction;
|
||||
|
||||
const ImageAttachment({
|
||||
Key key,
|
||||
@@ -23,6 +24,7 @@ class ImageAttachment extends StatelessWidget {
|
||||
this.messageTheme,
|
||||
this.showTitle = true,
|
||||
this.onShowMessage,
|
||||
this.onReturnAction,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@@ -42,8 +44,8 @@ class ImageAttachment extends StatelessWidget {
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
onTap: () async {
|
||||
var result = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) {
|
||||
@@ -64,6 +66,10 @@ class ImageAttachment extends StatelessWidget {
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
if (result != null) {
|
||||
onReturnAction(result);
|
||||
}
|
||||
},
|
||||
child: CachedNetworkImage(
|
||||
height: size?.height,
|
||||
|
||||
@@ -272,10 +272,7 @@ class _ImageFooterState extends State<ImageFooter> {
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: StreamChatTheme.of(context)
|
||||
.colorTheme
|
||||
.white
|
||||
.withOpacity(0.6),
|
||||
color: Colors.white.withOpacity(0.6),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
blurRadius: 8.0,
|
||||
@@ -286,7 +283,7 @@ class _ImageFooterState extends State<ImageFooter> {
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: const EdgeInsets.all(1),
|
||||
padding: const EdgeInsets.all(2),
|
||||
child: UserAvatar(
|
||||
user: widget.message.user,
|
||||
constraints:
|
||||
|
||||
@@ -101,24 +101,29 @@ class ImageHeader extends StatelessWidget implements PreferredSizeWidget {
|
||||
@override
|
||||
final Size preferredSize;
|
||||
|
||||
void _showMessageActionModalBottomSheet(BuildContext context) {
|
||||
void _showMessageActionModalBottomSheet(BuildContext context) async {
|
||||
final channel = StreamChannel.of(context).channel;
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierColor: StreamChatTheme.of(context).colorTheme.overlay,
|
||||
builder: (context) {
|
||||
return StreamChannel(
|
||||
channel: channel,
|
||||
child: ImageActionsModal(
|
||||
userName: userName,
|
||||
sentAt: sentAt,
|
||||
message: message,
|
||||
urls: urls,
|
||||
currentIndex: currentIndex,
|
||||
onShowMessage: onShowMessage,
|
||||
),
|
||||
);
|
||||
});
|
||||
var result = await showDialog(
|
||||
context: context,
|
||||
barrierColor: StreamChatTheme.of(context).colorTheme.overlay,
|
||||
builder: (context) {
|
||||
return StreamChannel(
|
||||
channel: channel,
|
||||
child: ImageActionsModal(
|
||||
userName: userName,
|
||||
sentAt: sentAt,
|
||||
message: message,
|
||||
urls: urls,
|
||||
currentIndex: currentIndex,
|
||||
onShowMessage: onShowMessage,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (result != null) {
|
||||
Navigator.pop(context, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -780,6 +780,16 @@ class _MessageListViewState extends State<MessageListView> {
|
||||
? StreamChatTheme.of(context).ownMessageTheme
|
||||
: StreamChatTheme.of(context).otherMessageTheme,
|
||||
onShowMessage: widget.onShowMessage,
|
||||
onReturnAction: (action) {
|
||||
switch (action) {
|
||||
case ReturnActionType.none:
|
||||
break;
|
||||
case ReturnActionType.reply:
|
||||
FocusScope.of(context).unfocus();
|
||||
widget.onMessageSwiped(message);
|
||||
break;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -930,6 +940,16 @@ class _MessageListViewState extends State<MessageListView> {
|
||||
readList: readList,
|
||||
allRead: allRead,
|
||||
onShowMessage: widget.onShowMessage,
|
||||
onReturnAction: (action) {
|
||||
switch (action) {
|
||||
case ReturnActionType.none:
|
||||
break;
|
||||
case ReturnActionType.reply:
|
||||
FocusScope.of(context).unfocus();
|
||||
widget.onMessageSwiped(message);
|
||||
break;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (!message.isDeleted && !message.isSystem && !message.isEphemeral) {
|
||||
|
||||
@@ -120,6 +120,7 @@ class MessageWidget extends StatefulWidget {
|
||||
final List<Read> readList;
|
||||
|
||||
final ShowMessageCallback onShowMessage;
|
||||
final ValueChanged<ReturnActionType> onReturnAction;
|
||||
|
||||
/// If true show the users username next to the timestamp of the message
|
||||
final bool showUsername;
|
||||
@@ -178,6 +179,7 @@ class MessageWidget extends StatefulWidget {
|
||||
this.onShowMessage,
|
||||
this.editMessageInputBuilder,
|
||||
this.textBuilder,
|
||||
this.onReturnAction,
|
||||
Map<String, AttachmentBuilder> customAttachmentBuilders,
|
||||
this.readList,
|
||||
this.padding,
|
||||
@@ -199,6 +201,7 @@ class MessageWidget extends StatefulWidget {
|
||||
MediaQuery.of(context).size.height * 0.3,
|
||||
),
|
||||
onShowMessage: onShowMessage,
|
||||
onReturnAction: onReturnAction,
|
||||
);
|
||||
},
|
||||
'video': (context, message, attachment) {
|
||||
@@ -211,6 +214,7 @@ class MessageWidget extends StatefulWidget {
|
||||
),
|
||||
message: message,
|
||||
onShowMessage: onShowMessage,
|
||||
onReturnAction: onReturnAction,
|
||||
);
|
||||
},
|
||||
'giphy': (context, message, attachment) {
|
||||
@@ -223,6 +227,7 @@ class MessageWidget extends StatefulWidget {
|
||||
MediaQuery.of(context).size.height * 0.3,
|
||||
),
|
||||
onShowMessage: onShowMessage,
|
||||
onReturnAction: onReturnAction,
|
||||
);
|
||||
},
|
||||
'file': (context, message, attachment) {
|
||||
|
||||
@@ -15,6 +15,7 @@ class VideoAttachment extends StatefulWidget {
|
||||
final Size size;
|
||||
final Message message;
|
||||
final ShowMessageCallback onShowMessage;
|
||||
final ValueChanged<ReturnActionType> onReturnAction;
|
||||
|
||||
VideoAttachment({
|
||||
Key key,
|
||||
@@ -23,6 +24,7 @@ class VideoAttachment extends StatefulWidget {
|
||||
this.message,
|
||||
this.size,
|
||||
this.onShowMessage,
|
||||
this.onReturnAction,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@@ -84,10 +86,10 @@ class _VideoAttachmentState extends State<VideoAttachment> {
|
||||
});
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
onTap: () async {
|
||||
final channel = StreamChannel.of(context).channel;
|
||||
|
||||
Navigator.push(
|
||||
var res = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => StreamChannel(
|
||||
@@ -102,6 +104,10 @@ class _VideoAttachmentState extends State<VideoAttachment> {
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (res != null) {
|
||||
widget.onReturnAction(res);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
height: widget.size?.height,
|
||||
|
||||
Reference in New Issue
Block a user