feat: Added image actions modal
This commit is contained in:
@@ -35,7 +35,7 @@ class _FullScreenImageState extends State<FullScreenImage>
|
||||
|
||||
AnimationController _controller;
|
||||
PageController _pageController;
|
||||
|
||||
|
||||
int _currentPage;
|
||||
|
||||
@override
|
||||
@@ -53,56 +53,66 @@ class _FullScreenImageState extends State<FullScreenImage>
|
||||
body: Stack(
|
||||
children: [
|
||||
AnimatedBuilder(
|
||||
animation: _controller,
|
||||
builder: (context, snapshot) {
|
||||
return PageView.builder(
|
||||
controller: _pageController,
|
||||
onPageChanged: (val) {
|
||||
setState(() {
|
||||
_currentPage = val;
|
||||
});
|
||||
},
|
||||
itemBuilder: (context, position) {
|
||||
return PhotoView(
|
||||
imageProvider: CachedNetworkImageProvider(widget.urls[position]),
|
||||
maxScale: PhotoViewComputedScale.covered,
|
||||
minScale: PhotoViewComputedScale.contained,
|
||||
heroAttributes: PhotoViewHeroAttributes(
|
||||
tag: widget.urls,
|
||||
),
|
||||
backgroundDecoration: BoxDecoration(
|
||||
color: ColorTween(
|
||||
begin: StreamChatTheme.of(context)
|
||||
.channelTheme
|
||||
.channelHeaderTheme
|
||||
.color,
|
||||
end: Colors.black).lerp(_controller.value),
|
||||
),
|
||||
onTapUp: (a, b, c) {
|
||||
setState(() {
|
||||
_optionsShown = !_optionsShown;
|
||||
});
|
||||
if(_controller.isCompleted) {
|
||||
_controller.reverse();
|
||||
} else {
|
||||
_controller.forward();
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
itemCount: widget.urls.length,
|
||||
);
|
||||
}
|
||||
),
|
||||
animation: _controller,
|
||||
builder: (context, snapshot) {
|
||||
return PageView.builder(
|
||||
controller: _pageController,
|
||||
onPageChanged: (val) {
|
||||
setState(() {
|
||||
_currentPage = val;
|
||||
});
|
||||
},
|
||||
itemBuilder: (context, position) {
|
||||
return PhotoView(
|
||||
imageProvider:
|
||||
CachedNetworkImageProvider(widget.urls[position]),
|
||||
maxScale: PhotoViewComputedScale.covered,
|
||||
minScale: PhotoViewComputedScale.contained,
|
||||
heroAttributes: PhotoViewHeroAttributes(
|
||||
tag: widget.urls,
|
||||
),
|
||||
backgroundDecoration: BoxDecoration(
|
||||
color: ColorTween(
|
||||
begin: StreamChatTheme.of(context)
|
||||
.channelTheme
|
||||
.channelHeaderTheme
|
||||
.color,
|
||||
end: Colors.black)
|
||||
.lerp(_controller.value),
|
||||
),
|
||||
onTapUp: (a, b, c) {
|
||||
setState(() {
|
||||
_optionsShown = !_optionsShown;
|
||||
});
|
||||
if (_controller.isCompleted) {
|
||||
_controller.reverse();
|
||||
} else {
|
||||
_controller.forward();
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
itemCount: widget.urls.length,
|
||||
);
|
||||
}),
|
||||
AnimatedOpacity(
|
||||
opacity: _optionsShown ? 1.0 : 0.0,
|
||||
duration: Duration(milliseconds: 300),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ImageHeader(userName: widget.userName, sentAt: 'Sent at${Jiffy(widget.sentAt.toLocal())
|
||||
.format(' HH:mm')}',),
|
||||
ImageFooter(currentPage: _currentPage, totalPages: widget.urls.length,),
|
||||
ImageHeader(
|
||||
userName: widget.userName,
|
||||
sentAt:
|
||||
'Sent at${Jiffy(widget.sentAt.toLocal()).format(' HH:mm')}',
|
||||
onBackPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
ImageFooter(
|
||||
currentPage: _currentPage,
|
||||
totalPages: widget.urls.length,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../stream_chat_flutter.dart';
|
||||
import 'stream_icons.dart';
|
||||
|
||||
class ImageActionsModal extends StatelessWidget {
|
||||
final String userName;
|
||||
final String sentAt;
|
||||
|
||||
ImageActionsModal({this.userName, this.sentAt});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
Colors.black.withOpacity(0.8),
|
||||
Colors.transparent,
|
||||
],
|
||||
stops: [0.0, 0.4],
|
||||
)
|
||||
),
|
||||
)
|
||||
),
|
||||
_buildPage(context),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPage(context) {
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Container(
|
||||
width: 40.0,
|
||||
),
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
userName,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
sentAt,
|
||||
style:
|
||||
StreamChatTheme.of(context).channelPreviewTheme.subtitle.copyWith(color: Colors.white.withOpacity(0.5)),
|
||||
),
|
||||
],
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
StreamIcons.close,
|
||||
size: 24.0,
|
||||
color: Colors.white,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width / 1.8,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Material(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
color: Color(0xffe5e5e5),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: ListTile.divideTiles(
|
||||
context: context,
|
||||
tiles: [
|
||||
_buildButton(context, 'Reply', StreamIcons.curve_line_down_left, () {}),
|
||||
_buildButton(context, 'Show in Chat', StreamIcons.eye, () {}),
|
||||
_buildButton(context, 'Save Image', StreamIcons.save_1, () {}),
|
||||
_buildButton(context, 'Copy', StreamIcons.copy, () {}),
|
||||
_buildButton(context, 'Delete', StreamIcons.delete, () {}, color: Colors.red),
|
||||
],
|
||||
).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildButton(context, String title, IconData iconData, VoidCallback onTap, {Color color}) {
|
||||
var titleStyle = TextStyle(
|
||||
fontSize: 14.5,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
|
||||
return ListTile(
|
||||
dense: true,
|
||||
title: Text(
|
||||
title,
|
||||
style: color == null ? titleStyle : titleStyle.copyWith(color: color),
|
||||
),
|
||||
leading: Icon(
|
||||
iconData,
|
||||
color: color ?? StreamChatTheme.of(context).primaryIconTheme.color,
|
||||
size: 24.0,
|
||||
),
|
||||
onTap: onTap,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import 'package:stream_chat_flutter/src/stream_icons.dart';
|
||||
|
||||
import './channel_name.dart';
|
||||
import 'channel_image.dart';
|
||||
import 'image_actions_modal.dart';
|
||||
import 'stream_channel.dart';
|
||||
|
||||
class ImageHeader extends StatelessWidget implements PreferredSizeWidget {
|
||||
@@ -63,7 +64,9 @@ class ImageHeader extends StatelessWidget implements PreferredSizeWidget {
|
||||
color: Colors.black,
|
||||
size: 24.0,
|
||||
),
|
||||
onPressed: () {},
|
||||
onPressed: () {
|
||||
_showMessageActionModalBottomSheet(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
centerTitle: true,
|
||||
@@ -98,4 +101,15 @@ class ImageHeader extends StatelessWidget implements PreferredSizeWidget {
|
||||
|
||||
@override
|
||||
final Size preferredSize;
|
||||
|
||||
void _showMessageActionModalBottomSheet(BuildContext context) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return ImageActionsModal(
|
||||
userName: userName,
|
||||
sentAt: sentAt,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user