feat: Added image actions modal

This commit is contained in:
Deven Joshi
2020-11-13 19:41:45 +05:30
parent 3ad6a25a82
commit 64ed2b2187
3 changed files with 215 additions and 46 deletions
+55 -45
View File
@@ -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,
),
],
),
),
+145
View File
@@ -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,
);
}
}
+15 -1
View File
@@ -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,
);
});
}
}