Implement mediaplayer and content viewer

This commit is contained in:
Christian Pauly 2020-01-17 11:08:12 +01:00
parent dcf3e312cf
commit bd36e3039e
5 changed files with 183 additions and 45 deletions

View file

@ -8,8 +8,10 @@ import 'matrix.dart';
class Avatar extends StatelessWidget { class Avatar extends StatelessWidget {
final MxContent mxContent; final MxContent mxContent;
final double size; final double size;
final Function onTap;
const Avatar(this.mxContent, {this.size = 40, Key key}) : super(key: key); const Avatar(this.mxContent, {this.size = 40, this.onTap, Key key})
: super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -19,21 +21,24 @@ class Avatar extends StatelessWidget {
height: size * MediaQuery.of(context).devicePixelRatio, height: size * MediaQuery.of(context).devicePixelRatio,
method: ThumbnailMethod.scale, method: ThumbnailMethod.scale,
); );
return CircleAvatar( return InkWell(
radius: size / 2, onTap: onTap,
backgroundImage: mxContent.mxc?.isNotEmpty ?? false child: CircleAvatar(
? kIsWeb radius: size / 2,
? NetworkImage( backgroundImage: mxContent.mxc?.isNotEmpty ?? false
src, ? kIsWeb
) ? NetworkImage(
: CachedNetworkImageProvider( src,
src, )
) : CachedNetworkImageProvider(
: null, src,
backgroundColor: Theme.of(context).secondaryHeaderColor, )
child: mxContent.mxc.isEmpty : null,
? Text("@", style: TextStyle(color: Colors.blueGrey)) backgroundColor: Theme.of(context).secondaryHeaderColor,
: null, child: mxContent.mxc.isEmpty
? Text("@", style: TextStyle(color: Colors.blueGrey))
: null,
),
); );
} }
} }

View file

@ -1,5 +1,7 @@
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/utils/app_route.dart';
import 'package:fluffychat/views/content_web_view.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -29,27 +31,35 @@ class ContentBanner extends StatelessWidget {
height: bannerSize, height: bannerSize,
method: ThumbnailMethod.scale, method: ThumbnailMethod.scale,
); );
return Container( return InkWell(
height: 200, onTap: () => Navigator.of(context).push(
color: Theme.of(context).secondaryHeaderColor, AppRoute.defaultRoute(
child: !loading context,
? mxContent.mxc?.isNotEmpty ?? false ContentWebView(mxContent),
? kIsWeb ),
? Image.network( ),
src, child: Container(
height: 200, height: 200,
fit: BoxFit.cover, color: Theme.of(context).secondaryHeaderColor,
) child: !loading
: CachedNetworkImage( ? mxContent.mxc?.isNotEmpty ?? false
imageUrl: src, ? kIsWeb
height: 200, ? Image.network(
fit: BoxFit.cover, src,
placeholder: (c, s) => height: 200,
Center(child: CircularProgressIndicator()), fit: BoxFit.cover,
errorWidget: (c, s, o) => Icon(Icons.error, size: 200), )
) : CachedNetworkImage(
: Icon(defaultIcon, size: 200) imageUrl: src,
: Icon(defaultIcon, size: 200), height: 200,
fit: BoxFit.cover,
placeholder: (c, s) =>
Center(child: CircularProgressIndicator()),
errorWidget: (c, s, o) => Icon(Icons.error, size: 200),
)
: Icon(defaultIcon, size: 200)
: Icon(defaultIcon, size: 200),
),
); );
} }
} }

View file

@ -2,7 +2,9 @@ import 'package:bubble/bubble.dart';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/components/dialogs/redact_message_dialog.dart'; import 'package:fluffychat/components/dialogs/redact_message_dialog.dart';
import 'package:fluffychat/components/message_content.dart'; import 'package:fluffychat/components/message_content.dart';
import 'package:fluffychat/utils/app_route.dart';
import 'package:fluffychat/utils/date_time_extension.dart'; import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/views/content_web_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -26,8 +28,10 @@ class Message extends StatelessWidget {
final bool ownMessage = event.senderId == client.userID; final bool ownMessage = event.senderId == client.userID;
Alignment alignment = ownMessage ? Alignment.topRight : Alignment.topLeft; Alignment alignment = ownMessage ? Alignment.topRight : Alignment.topLeft;
Color color = Theme.of(context).secondaryHeaderColor; Color color = Theme.of(context).secondaryHeaderColor;
final bool sameSender = final bool sameSender = nextEvent != null &&
nextEvent != null ? nextEvent.sender.id == event.sender.id : false; [EventTypes.Message, EventTypes.Sticker].contains(nextEvent.type)
? nextEvent.sender.id == event.sender.id
: false;
BubbleNip nip = sameSender BubbleNip nip = sameSender
? BubbleNip.no ? BubbleNip.no
: ownMessage ? BubbleNip.rightBottom : BubbleNip.leftBottom; : ownMessage ? BubbleNip.rightBottom : BubbleNip.leftBottom;
@ -151,8 +155,17 @@ class Message extends StatelessWidget {
), ),
), ),
]; ];
final Widget avatarOrSizedBox = final Widget avatarOrSizedBox = sameSender
sameSender ? SizedBox(width: 40) : Avatar(event.sender.avatarUrl); ? SizedBox(width: 40)
: Avatar(
event.sender.avatarUrl,
onTap: () => Navigator.of(context).push(
AppRoute.defaultRoute(
context,
ContentWebView(event.sender.avatarUrl),
),
),
);
if (ownMessage) { if (ownMessage) {
rowChildren.add(avatarOrSizedBox); rowChildren.add(avatarOrSizedBox);
} else { } else {

View file

@ -1,6 +1,8 @@
import 'package:bubble/bubble.dart'; import 'package:bubble/bubble.dart';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/utils/app_route.dart';
import 'package:fluffychat/views/content_web_view.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:link_text/link_text.dart'; import 'package:link_text/link_text.dart';
@ -58,9 +60,11 @@ class MessageContent extends StatelessWidget {
radius: Radius.circular(10), radius: Radius.circular(10),
elevation: 0, elevation: 0,
child: InkWell( child: InkWell(
onTap: () => launch( onTap: () => Navigator.of(context).push(
MxContent(event.content["url"]) AppRoute.defaultRoute(
.getDownloadLink(Matrix.of(context).client), context,
ContentWebView(MxContent(event.content["url"])),
),
), ),
child: kIsWeb child: kIsWeb
? Image.network( ? Image.network(
@ -74,8 +78,78 @@ class MessageContent extends StatelessWidget {
), ),
); );
case MessageTypes.Audio: case MessageTypes.Audio:
case MessageTypes.File: if (textOnly) {
return Text(
"${event.sender.calcDisplayname()} sent an audio message",
maxLines: maxLines,
style: TextStyle(
color: textColor,
decoration:
event.redacted ? TextDecoration.lineThrough : null,
),
);
}
return Container(
width: 200,
child: RaisedButton(
color: Colors.blueGrey,
child: Row(
children: <Widget>[
Icon(Icons.play_arrow, color: Colors.white),
Text(
"Play ${event.body}",
overflow: TextOverflow.fade,
softWrap: false,
maxLines: 1,
style: TextStyle(color: Colors.white),
),
],
),
onPressed: () => Navigator.of(context).push(
AppRoute.defaultRoute(
context,
ContentWebView(MxContent(event.content["url"])),
),
),
),
);
case MessageTypes.Video: case MessageTypes.Video:
if (textOnly) {
return Text(
"${event.sender.calcDisplayname()} sent a video message",
maxLines: maxLines,
style: TextStyle(
color: textColor,
decoration:
event.redacted ? TextDecoration.lineThrough : null,
),
);
}
return Container(
width: 200,
child: RaisedButton(
color: Colors.blueGrey,
child: Row(
children: <Widget>[
Icon(Icons.play_arrow, color: Colors.white),
Text(
"Play ${event.body}",
overflow: TextOverflow.fade,
softWrap: false,
maxLines: 1,
style: TextStyle(color: Colors.white),
),
],
),
onPressed: () => Navigator.of(context).push(
AppRoute.defaultRoute(
context,
ContentWebView(MxContent(event.content["url"])),
),
),
),
);
case MessageTypes.File:
if (textOnly) { if (textOnly) {
return Text( return Text(
"${event.sender.calcDisplayname()} sent a file", "${event.sender.calcDisplayname()} sent a file",
@ -96,6 +170,7 @@ class MessageContent extends StatelessWidget {
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
softWrap: false, softWrap: false,
maxLines: 1, maxLines: 1,
style: TextStyle(color: Colors.white),
), ),
onPressed: () => launch( onPressed: () => launch(
MxContent(event.content["url"]) MxContent(event.content["url"])

View file

@ -0,0 +1,35 @@
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/components/matrix.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:webview_flutter/webview_flutter.dart';
class ContentWebView extends StatelessWidget {
final MxContent content;
const ContentWebView(this.content);
@override
Widget build(BuildContext context) {
final String url = content.getDownloadLink(Matrix.of(context).client);
print(url);
return Scaffold(
appBar: AppBar(
title: Text(
"Content viewer",
),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.file_download,
),
onPressed: () => launch(url),
),
],
),
body: WebView(
initialUrl: url,
),
);
}
}