Receive sharing intent
This commit is contained in:
parent
4bf7cb9f4b
commit
8c1ed0de1e
|
@ -1,4 +1,6 @@
|
||||||
# Version 0.11.0 - 2020-04-02
|
# Version 0.11.0 - 2020-04-02
|
||||||
|
### Features:
|
||||||
|
- Share content with FluffyChat
|
||||||
### Fixes:
|
### Fixes:
|
||||||
- Minor bugfixes
|
- Minor bugfixes
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
android:icon="@mipmap/launcher_icon">
|
android:icon="@mipmap/launcher_icon">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTask"
|
||||||
android:theme="@style/LaunchTheme"
|
android:theme="@style/LaunchTheme"
|
||||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
|
@ -38,6 +38,27 @@
|
||||||
android:scheme="https"
|
android:scheme="https"
|
||||||
android:host="matrix.to"/>
|
android:host="matrix.to"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<data android:mimeType="text/*" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<data android:mimeType="document/*" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<data android:mimeType="image/*" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<data android:mimeType="video/*" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
|
||||||
</activity>
|
</activity>
|
||||||
<!-- Don't delete the meta-data below.
|
<!-- Don't delete the meta-data below.
|
||||||
|
|
67
lib/components/image_bubble.dart
Normal file
67
lib/components/image_bubble.dart
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
import 'package:bubble/bubble.dart';
|
||||||
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:fluffychat/utils/matrix_file_extension.dart';
|
||||||
|
|
||||||
|
class ImageBubble extends StatefulWidget {
|
||||||
|
final Event event;
|
||||||
|
|
||||||
|
const ImageBubble(this.event, {Key key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_ImageBubbleState createState() => _ImageBubbleState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ImageBubbleState extends State<ImageBubble> {
|
||||||
|
MatrixFile _file;
|
||||||
|
dynamic _error;
|
||||||
|
|
||||||
|
Future<MatrixFile> _getFile() async {
|
||||||
|
if (_file != null) return _file;
|
||||||
|
return widget.event.downloadAndDecryptAttachment();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final int size = 400;
|
||||||
|
return Bubble(
|
||||||
|
padding: BubbleEdges.all(0),
|
||||||
|
radius: Radius.circular(10),
|
||||||
|
elevation: 0,
|
||||||
|
child: Container(
|
||||||
|
height: size.toDouble(),
|
||||||
|
width: size.toDouble(),
|
||||||
|
child: Builder(
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
if (_error != null) {
|
||||||
|
return Center(
|
||||||
|
child: Text(
|
||||||
|
_error.toString(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (_file != null) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () => _file.open(),
|
||||||
|
child: Image.memory(
|
||||||
|
_file.bytes,
|
||||||
|
width: size.toDouble(),
|
||||||
|
height: size.toDouble(),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_getFile().then((MatrixFile file) {
|
||||||
|
setState(() => _file = file);
|
||||||
|
}, onError: (error) {
|
||||||
|
setState(() => _error = error);
|
||||||
|
});
|
||||||
|
return Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -77,7 +77,16 @@ class ChatListItem extends StatelessWidget {
|
||||||
|
|
||||||
if (room.membership == Membership.join) {
|
if (room.membership == Membership.join) {
|
||||||
if (Matrix.of(context).shareContent != null) {
|
if (Matrix.of(context).shareContent != null) {
|
||||||
unawaited(room.sendEvent(Matrix.of(context).shareContent));
|
if (Matrix.of(context).shareContent["msgtype"] ==
|
||||||
|
"chat.fluffy.shared_file") {
|
||||||
|
await Matrix.of(context).tryRequestWithErrorToast(
|
||||||
|
room.sendFileEvent(
|
||||||
|
Matrix.of(context).shareContent["file"],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
unawaited(room.sendEvent(Matrix.of(context).shareContent));
|
||||||
|
}
|
||||||
Matrix.of(context).shareContent = null;
|
Matrix.of(context).shareContent = null;
|
||||||
}
|
}
|
||||||
await Navigator.pushAndRemoveUntil(
|
await Navigator.pushAndRemoveUntil(
|
||||||
|
|
|
@ -394,7 +394,6 @@ class _InheritedMatrix extends InheritedWidget {
|
||||||
bool update = old.data.client.accessToken != this.data.client.accessToken ||
|
bool update = old.data.client.accessToken != this.data.client.accessToken ||
|
||||||
old.data.client.userID != this.data.client.userID ||
|
old.data.client.userID != this.data.client.userID ||
|
||||||
old.data.client.matrixVersions != this.data.client.matrixVersions ||
|
old.data.client.matrixVersions != this.data.client.matrixVersions ||
|
||||||
old.data.client.lazyLoadMembers != this.data.client.lazyLoadMembers ||
|
|
||||||
old.data.client.deviceID != this.data.client.deviceID ||
|
old.data.client.deviceID != this.data.client.deviceID ||
|
||||||
old.data.client.deviceName != this.data.client.deviceName ||
|
old.data.client.deviceName != this.data.client.deviceName ||
|
||||||
old.data.client.homeserver != this.data.client.homeserver;
|
old.data.client.homeserver != this.data.client.homeserver;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:bubble/bubble.dart';
|
import 'package:bubble/bubble.dart';
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/components/audio_player.dart';
|
import 'package:fluffychat/components/audio_player.dart';
|
||||||
|
import 'package:fluffychat/components/image_bubble.dart';
|
||||||
import 'package:fluffychat/i18n/i18n.dart';
|
import 'package:fluffychat/i18n/i18n.dart';
|
||||||
import 'package:fluffychat/utils/event_extension.dart';
|
import 'package:fluffychat/utils/event_extension.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
@ -26,37 +27,7 @@ class MessageContent extends StatelessWidget {
|
||||||
switch (event.messageType) {
|
switch (event.messageType) {
|
||||||
case MessageTypes.Image:
|
case MessageTypes.Image:
|
||||||
case MessageTypes.Sticker:
|
case MessageTypes.Sticker:
|
||||||
final int size = 400;
|
return ImageBubble(event);
|
||||||
return Bubble(
|
|
||||||
padding: BubbleEdges.all(0),
|
|
||||||
radius: Radius.circular(10),
|
|
||||||
elevation: 0,
|
|
||||||
child: Container(
|
|
||||||
height: size.toDouble(),
|
|
||||||
width: size.toDouble(),
|
|
||||||
child: FutureBuilder<MatrixFile>(
|
|
||||||
future: event.downloadAndDecryptAttachment(),
|
|
||||||
builder: (BuildContext context, snapshot) {
|
|
||||||
if (snapshot.hasError) {
|
|
||||||
return Center(
|
|
||||||
child: Text(
|
|
||||||
snapshot.error.toString(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (snapshot.hasData) {
|
|
||||||
return InkWell(
|
|
||||||
onTap: () => snapshot.data.open(),
|
|
||||||
child: Image.memory(snapshot.data.bytes),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return Center(
|
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
case MessageTypes.Audio:
|
case MessageTypes.Audio:
|
||||||
return AudioPlayer(
|
return AudioPlayer(
|
||||||
event,
|
event,
|
||||||
|
|
|
@ -86,7 +86,6 @@ class Store extends StoreAPI {
|
||||||
newDeviceID: credentials["deviceID"],
|
newDeviceID: credentials["deviceID"],
|
||||||
newDeviceName: credentials["deviceName"],
|
newDeviceName: credentials["deviceName"],
|
||||||
newHomeserver: credentials["homeserver"],
|
newHomeserver: credentials["homeserver"],
|
||||||
newLazyLoadMembers: credentials["lazyLoadMembers"],
|
|
||||||
newMatrixVersions: List<String>.from(credentials["matrixVersions"] ?? []),
|
newMatrixVersions: List<String>.from(credentials["matrixVersions"] ?? []),
|
||||||
newToken: credentials["token"],
|
newToken: credentials["token"],
|
||||||
newUserID: credentials["userID"],
|
newUserID: credentials["userID"],
|
||||||
|
@ -104,7 +103,6 @@ class Store extends StoreAPI {
|
||||||
"deviceID": client.deviceID,
|
"deviceID": client.deviceID,
|
||||||
"deviceName": client.deviceName,
|
"deviceName": client.deviceName,
|
||||||
"homeserver": client.homeserver,
|
"homeserver": client.homeserver,
|
||||||
"lazyLoadMembers": client.lazyLoadMembers,
|
|
||||||
"matrixVersions": client.matrixVersions,
|
"matrixVersions": client.matrixVersions,
|
||||||
"token": client.accessToken,
|
"token": client.accessToken,
|
||||||
"userID": client.userID,
|
"userID": client.userID,
|
||||||
|
@ -175,7 +173,6 @@ class ExtendedStore extends Store implements ExtendedStoreAPI {
|
||||||
newUserID: clientList["matrix_id"],
|
newUserID: clientList["matrix_id"],
|
||||||
newDeviceID: clientList["device_id"],
|
newDeviceID: clientList["device_id"],
|
||||||
newDeviceName: clientList["device_name"],
|
newDeviceName: clientList["device_name"],
|
||||||
newLazyLoadMembers: clientList["lazy_load_members"] == 1,
|
|
||||||
newMatrixVersions:
|
newMatrixVersions:
|
||||||
clientList["matrix_versions"].toString().split(","),
|
clientList["matrix_versions"].toString().split(","),
|
||||||
newPrevBatch: null,
|
newPrevBatch: null,
|
||||||
|
|
|
@ -40,10 +40,6 @@ class AppInfo extends StatelessWidget {
|
||||||
title: Text("Supported versions:"),
|
title: Text("Supported versions:"),
|
||||||
subtitle: Text(client.matrixVersions.toString()),
|
subtitle: Text(client.matrixVersions.toString()),
|
||||||
),
|
),
|
||||||
ListTile(
|
|
||||||
title: Text("Lazy Loading members enabled:"),
|
|
||||||
subtitle: Text(client.lazyLoadMembers.toString()),
|
|
||||||
),
|
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text("Device name:"),
|
title: Text("Device name:"),
|
||||||
subtitle: Text(client.deviceName),
|
subtitle: Text(client.deviceName),
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/components/list_items/public_room_list_item.dart';
|
import 'package:fluffychat/components/list_items/public_room_list_item.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
||||||
import 'package:uni_links/uni_links.dart';
|
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
|
||||||
|
|
||||||
import '../components/dialogs/simple_dialogs.dart';
|
import '../components/dialogs/simple_dialogs.dart';
|
||||||
import '../components/theme_switcher.dart';
|
import '../components/theme_switcher.dart';
|
||||||
|
@ -103,35 +103,63 @@ class _ChatListState extends State<ChatList> {
|
||||||
});
|
});
|
||||||
setState(() => null);
|
setState(() => null);
|
||||||
});
|
});
|
||||||
initUniLinks();
|
_initReceiveSharingINtent();
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamSubscription _intentDataStreamSubscription;
|
StreamSubscription _intentDataStreamSubscription;
|
||||||
|
|
||||||
StreamSubscription _onUniLinksub;
|
StreamSubscription _intentFileStreamSubscription;
|
||||||
|
|
||||||
Future<void> initUniLinks() async {
|
void _processIncomingSharedFiles(List<SharedMediaFile> files) {
|
||||||
if (kIsWeb) return;
|
if (files?.isEmpty ?? true) return;
|
||||||
_onUniLinksub ??= getLinksStream().listen(
|
if (Navigator.of(context).canPop()) {
|
||||||
(String initialLink) {
|
Navigator.of(context).popUntil((r) => r.isFirst);
|
||||||
try {
|
}
|
||||||
if (initialLink?.isEmpty ?? true) return;
|
final File file = File(files.first.path);
|
||||||
if (initialLink.startsWith("https://matrix.to/#/")) {
|
|
||||||
UrlLauncher(context, initialLink).openMatrixToUrl();
|
Matrix.of(context).shareContent = {
|
||||||
}
|
"msgtype": "chat.fluffy.shared_file",
|
||||||
} on PlatformException {
|
"file": MatrixFile(
|
||||||
debugPrint("initUniLinks failed during platform exception");
|
bytes: file.readAsBytesSync(),
|
||||||
}
|
path: file.path,
|
||||||
},
|
|
||||||
onError: (error) => Scaffold.of(context).showSnackBar(
|
|
||||||
SnackBar(
|
|
||||||
content: Text(
|
|
||||||
I18n.of(context).oopsSomethingWentWrong + " " + error.toString(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
};
|
||||||
|
setState(() => null);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _processIncomingSharedText(String text) {
|
||||||
|
if (text == null) return;
|
||||||
|
if (Navigator.of(context).canPop()) {
|
||||||
|
Navigator.of(context).popUntil((r) => r.isFirst);
|
||||||
|
}
|
||||||
|
if (text.startsWith("https://matrix.to/#/")) {
|
||||||
|
UrlLauncher(context, text).openMatrixToUrl();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Matrix.of(context).shareContent = {
|
||||||
|
"msgtype": "m.text",
|
||||||
|
"body": text,
|
||||||
|
};
|
||||||
|
setState(() => null);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _initReceiveSharingINtent() {
|
||||||
|
if (kIsWeb) return;
|
||||||
|
|
||||||
|
// For sharing images coming from outside the app while the app is in the memory
|
||||||
|
_intentFileStreamSubscription = ReceiveSharingIntent.getMediaStream()
|
||||||
|
.listen(_processIncomingSharedFiles, onError: print);
|
||||||
|
|
||||||
|
// For sharing images coming from outside the app while the app is closed
|
||||||
|
ReceiveSharingIntent.getInitialMedia().then(_processIncomingSharedFiles);
|
||||||
|
|
||||||
|
// For sharing or opening urls/text coming from outside the app while the app is in the memory
|
||||||
|
_intentDataStreamSubscription = ReceiveSharingIntent.getTextStream()
|
||||||
|
.listen(_processIncomingSharedText, onError: print);
|
||||||
|
|
||||||
|
// For sharing or opening urls/text coming from outside the app while the app is closed
|
||||||
|
ReceiveSharingIntent.getInitialText().then(_processIncomingSharedText);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -141,7 +169,7 @@ class _ChatListState extends State<ChatList> {
|
||||||
() => setState(() => null),
|
() => setState(() => null),
|
||||||
);
|
);
|
||||||
_intentDataStreamSubscription?.cancel();
|
_intentDataStreamSubscription?.cancel();
|
||||||
_onUniLinksub?.cancel();
|
_intentFileStreamSubscription?.cancel();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
18
pubspec.lock
18
pubspec.lock
|
@ -124,8 +124,8 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: "63a5d5dba37bdf3d1106fdf6f11760bfd7d2904c"
|
ref: "31871235a59af16c7c163f767d7a7f8486457429"
|
||||||
resolved-ref: "63a5d5dba37bdf3d1106fdf6f11760bfd7d2904c"
|
resolved-ref: "31871235a59af16c7c163f767d7a7f8486457429"
|
||||||
url: "https://gitlab.com/famedly/famedlysdk.git"
|
url: "https://gitlab.com/famedly/famedlysdk.git"
|
||||||
source: git
|
source: git
|
||||||
version: "0.0.1"
|
version: "0.0.1"
|
||||||
|
@ -510,6 +510,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.5"
|
version: "2.0.5"
|
||||||
|
receive_sharing_intent:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: receive_sharing_intent
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.3"
|
||||||
share:
|
share:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -641,13 +648,6 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.6"
|
version: "1.1.6"
|
||||||
uni_links:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: uni_links
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.2.0"
|
|
||||||
universal_html:
|
universal_html:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -27,7 +27,7 @@ dependencies:
|
||||||
famedlysdk:
|
famedlysdk:
|
||||||
git:
|
git:
|
||||||
url: https://gitlab.com/famedly/famedlysdk.git
|
url: https://gitlab.com/famedly/famedlysdk.git
|
||||||
ref: 63a5d5dba37bdf3d1106fdf6f11760bfd7d2904c
|
ref: 31871235a59af16c7c163f767d7a7f8486457429
|
||||||
|
|
||||||
localstorage: ^3.0.1+4
|
localstorage: ^3.0.1+4
|
||||||
bubble: ^1.1.9+1
|
bubble: ^1.1.9+1
|
||||||
|
@ -47,7 +47,7 @@ dependencies:
|
||||||
flutter_secure_storage: ^3.3.1+1
|
flutter_secure_storage: ^3.3.1+1
|
||||||
http: ^0.12.0+4
|
http: ^0.12.0+4
|
||||||
universal_html: ^1.1.12
|
universal_html: ^1.1.12
|
||||||
uni_links: ^0.2.0
|
receive_sharing_intent: ^1.3.3
|
||||||
flutter_svg: ^0.17.1
|
flutter_svg: ^0.17.1
|
||||||
flutter_slidable: ^0.5.4
|
flutter_slidable: ^0.5.4
|
||||||
photo_view: ^0.9.2
|
photo_view: ^0.9.2
|
||||||
|
|
Loading…
Reference in a new issue