diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index b7171e7245..355548bf6c 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -79,25 +79,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/ios/FluffyChat Share/ShareViewController.swift b/ios/FluffyChat Share/ShareViewController.swift
index 96d921432f..e56ab17539 100644
--- a/ios/FluffyChat Share/ShareViewController.swift
+++ b/ios/FluffyChat Share/ShareViewController.swift
@@ -5,7 +5,7 @@ import Photos
class ShareViewController: SLComposeServiceViewController {
// TODO: IMPORTANT: This should be your host app bundle identifier
- let hostAppBundleIdentifier = "im.fluffychat.app"
+ let hostAppBundleIdentifier = "com.linagora.ios.twake"
let sharedKey = "ShareKey"
var sharedMedia: [SharedMediaFile] = []
var sharedText: [String] = []
@@ -200,7 +200,7 @@ class ShareViewController: SLComposeServiceViewController {
}
private func redirectToHostApp(type: RedirectType) {
- let url = URL(string: "ShareMedia://dataUrl=\(sharedKey)#\(type)")
+ let url = URL(string: "ShareMedia-\(hostAppBundleIdentifier)://dataUrl=\(sharedKey)#\(type)")
var responder = self as UIResponder?
let selectorOpenURL = sel_registerName("openURL:")
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index af4e85702e..c34a50fe35 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -35,7 +35,7 @@
im.fluffychat.app.uris
CFBundleURLSchemes
- ShareMedia
+ ShareMedia-$(PRODUCT_BUNDLE_IDENTIFIER)
twake.chat
matrix
diff --git a/lib/config/go_routes/go_router.dart b/lib/config/go_routes/go_router.dart
index 532d88dbe9..7f48d38259 100644
--- a/lib/config/go_routes/go_router.dart
+++ b/lib/config/go_routes/go_router.dart
@@ -8,6 +8,7 @@ import 'package:fluffychat/pages/chat_details/chat_details.dart';
import 'package:fluffychat/pages/chat_draft/draft_chat.dart';
import 'package:fluffychat/pages/chat_encryption_settings/chat_encryption_settings.dart';
import 'package:fluffychat/pages/homeserver_picker/homeserver_picker.dart';
+import 'package:fluffychat/pages/share/share.dart';
import 'package:fluffychat/pages/story/story_page.dart';
import 'package:fluffychat/utils/responsive/responsive_utils.dart';
import 'package:fluffychat/widgets/layouts/adaptive_layout/adaptive_scaffold.dart';
@@ -36,6 +37,7 @@ import 'package:fluffychat/widgets/log_view.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/cupertino.dart';
import 'package:go_router/go_router.dart';
+import 'package:matrix/matrix.dart';
abstract class AppRoutes {
static FutureOr loggedInRedirect(
@@ -160,12 +162,14 @@ abstract class AppRoutes {
routes: [
GoRoute(
path: ':roomid',
- pageBuilder: (context, state) => defaultPageBuilder(
- context,
- Chat(
- roomId: state.pathParameters['roomid']!,
- ),
- ),
+ pageBuilder: (context, state) {
+ return defaultPageBuilder(
+ context,
+ Chat(
+ roomId: state.pathParameters['roomid']!,
+ ),
+ );
+ },
redirect: loggedOutRedirect,
),
],
@@ -346,13 +350,17 @@ abstract class AppRoutes {
),
GoRoute(
path: ':roomid',
- pageBuilder: (context, state) => defaultPageBuilder(
- context,
- Chat(
- roomId: state.pathParameters['roomid']!,
- key: Key(state.pathParameters['roomid']!),
- ),
- ),
+ pageBuilder: (context, state) {
+ final shareFile = state.extra as MatrixFile?;
+ return defaultPageBuilder(
+ context,
+ Chat(
+ roomId: state.pathParameters['roomid']!,
+ key: Key(state.pathParameters['roomid']!),
+ shareFile: shareFile,
+ ),
+ );
+ },
redirect: loggedOutRedirect,
routes: [
GoRoute(
@@ -431,6 +439,14 @@ abstract class AppRoutes {
),
],
),
+ GoRoute(
+ path: '/share',
+ pageBuilder: (context, state) => defaultPageBuilder(
+ context,
+ const Share(),
+ ),
+ redirect: loggedOutRedirect,
+ ),
],
),
];
diff --git a/lib/pages/share/share.dart b/lib/pages/share/share.dart
new file mode 100644
index 0000000000..7fc97df475
--- /dev/null
+++ b/lib/pages/share/share.dart
@@ -0,0 +1,66 @@
+import 'package:collection/collection.dart';
+import 'package:fluffychat/di/global/get_it_initializer.dart';
+import 'package:fluffychat/domain/usecase/send_file_interactor.dart';
+import 'package:fluffychat/pages/share/share_view.dart';
+import 'package:fluffychat/presentation/mixins/send_files_mixin.dart';
+import 'package:fluffychat/widgets/matrix.dart';
+import 'package:flutter/material.dart';
+import 'package:go_router/go_router.dart';
+import 'package:matrix/matrix.dart';
+import 'package:scroll_to_index/scroll_to_index.dart';
+
+class Share extends StatefulWidget {
+ const Share({super.key});
+
+ @override
+ State createState() => ShareController();
+}
+
+class ShareController extends State with SendFilesMixin {
+ final sendFileInteractor = getIt.get();
+
+ final isShowRecentlyChatsNotifier = ValueNotifier(true);
+
+ final AutoScrollController recentChatScrollController =
+ AutoScrollController();
+
+ final selectedRoomsNotifier = ValueNotifier([]);
+
+ void onSelectChat(String id) {
+ if (selectedRoomsNotifier.value.contains(id)) {
+ selectedRoomsNotifier.value.remove(id);
+ } else {
+ selectedRoomsNotifier.value.add(id);
+ }
+ selectedRoomsNotifier.value = selectedRoomsNotifier.value.sorted(
+ (current, next) => current.compareTo(next),
+ );
+ }
+
+ void toggleRecentlyChats() {
+ isShowRecentlyChatsNotifier.value = !isShowRecentlyChatsNotifier.value;
+ }
+
+ void shareTo(String roomId) async {
+ final room = Room(
+ id: selectedRoomsNotifier.value.first,
+ client: Matrix.of(context).client,
+ );
+ final shareContent = Matrix.of(context).shareContent;
+ if (shareContent != null) {
+ final shareFile = shareContent.tryGet('file');
+ if (shareContent.tryGet('msgtype') == 'chat.fluffy.shared_file') {
+ context.go('/rooms/${room.id}', extra: shareFile);
+ } else {
+ room.sendEvent(shareContent);
+ context.go('/rooms/${room.id}');
+ }
+ Matrix.of(context).shareContent = null;
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return ShareView(this);
+ }
+}
diff --git a/lib/pages/share/share_view.dart b/lib/pages/share/share_view.dart
new file mode 100644
index 0000000000..ea982049b4
--- /dev/null
+++ b/lib/pages/share/share_view.dart
@@ -0,0 +1,80 @@
+import 'package:fluffychat/pages/forward/recent_chat_list.dart';
+import 'package:fluffychat/pages/forward/recent_chat_title.dart';
+import 'package:fluffychat/pages/share/share.dart';
+import 'package:fluffychat/widgets/matrix.dart';
+import 'package:fluffychat/widgets/twake_components/twake_fab.dart';
+import 'package:fluffychat/widgets/twake_components/twake_icon_button.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_gen/gen_l10n/l10n.dart';
+import 'package:go_router/go_router.dart';
+
+class ShareView extends StatelessWidget {
+ const ShareView(this.controller, {super.key});
+
+ final ShareController controller;
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ centerTitle: true,
+ title: Text(
+ L10n.of(context)!.share,
+ style: Theme.of(context).textTheme.headlineLarge,
+ ),
+ leading: TwakeIconButton(
+ tooltip: L10n.of(context)!.cancel,
+ icon: Icons.close,
+ onPressed: () => context.pop(),
+ ),
+ ),
+ body: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16.0),
+ child: SingleChildScrollView(
+ child: Column(
+ children: [
+ RecentChatsTitle(
+ isShowRecentlyChats:
+ controller.isShowRecentlyChatsNotifier.value,
+ toggleRecentChat: controller.toggleRecentlyChats,
+ ),
+ ValueListenableBuilder(
+ valueListenable: controller.isShowRecentlyChatsNotifier,
+ builder: (context, isShowRecentlyChat, child) {
+ if (isShowRecentlyChat) {
+ return RecentChatList(
+ rooms: Matrix.of(context).client.rooms,
+ selectedEventsNotifier: controller.selectedRoomsNotifier,
+ onSelectedChat: (roomId) =>
+ controller.onSelectChat(roomId),
+ recentChatScrollController:
+ controller.recentChatScrollController,
+ );
+ }
+
+ return const SizedBox.shrink();
+ },
+ ),
+ ],
+ ),
+ ),
+ ),
+ floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
+ floatingActionButton: ValueListenableBuilder>(
+ valueListenable: controller.selectedRoomsNotifier,
+ builder: ((context, selectedChats, child) {
+ if (selectedChats.length != 1) {
+ return const SizedBox.shrink();
+ }
+ return TwakeFloatingActionButton(
+ icon: Icons.send,
+ size: 18.0,
+ onTap: () => controller.shareTo(
+ controller.selectedRoomsNotifier.value.first,
+ ),
+ );
+ }),
+ ),
+ );
+ }
+}
diff --git a/pubspec.lock b/pubspec.lock
index ab6ef6668e..3266eda48d 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1933,10 +1933,11 @@ packages:
receive_sharing_intent:
dependency: "direct main"
description:
- name: receive_sharing_intent
- sha256: "912bebb551bce75a14098891fd750305b30d53eba0d61cc70cd9973be9866e8d"
- url: "https://pub.dev"
- source: hosted
+ path: "."
+ ref: "receive-.txt-v2"
+ resolved-ref: "7ac2cccb3e1ac4bddce7e287adcb69726f368b89"
+ url: "git@github.com:krabbenprgr/receive_sharing_intent.git"
+ source: git
version: "1.4.5"
record:
dependency: "direct main"
diff --git a/pubspec.yaml b/pubspec.yaml
index a53a3bf87f..5a62d2130a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -77,7 +77,10 @@ dependencies:
punycode: ^1.0.0
qr_code_scanner: ^1.0.0
qr_flutter: ^4.0.0
- receive_sharing_intent: ^1.4.5
+ receive_sharing_intent:
+ git:
+ url: git@github.com:krabbenprgr/receive_sharing_intent.git
+ ref: receive-.txt-v2
record: ^4.4.4
scroll_to_index: ^3.0.1
share_plus: ^4.0.10+1