mirror of
				https://gitlab.com/famedly/fluffychat.git
				synced 2025-11-04 14:27:23 +01:00 
			
		
		
		
	chore: defaultly save files on Android
- defaultly save files on Android instead of share - add dedicated share button for files and images on Android - use ListTile instead of row to display file event - update file_picker_cross Signed-off-by: TheOneWithTheBraid <the-one@with-the-braid.cf>
This commit is contained in:
		
							parent
							
								
									10798ac7ff
								
							
						
					
					
						commit
						a9275fc4f6
					
				@ -25,7 +25,7 @@
 | 
			
		||||
    <uses-permission android:name="android.permission.CALL_PHONE" />
 | 
			
		||||
 | 
			
		||||
    <uses-sdk
 | 
			
		||||
            tools:overrideLibrary="io.wazo.callkeep, net.touchcapture.qr.flutterqr, com.cloudwebrtc.webrtc, org.webrtc, com.it_nomads.fluttersecurestorage, com.pichillilorenzo.flutter_inappwebview, com.example.video_compress, com.otaliastudios.transcoder, com.otaliastudios.opengl"/>
 | 
			
		||||
            tools:overrideLibrary="io.wazo.callkeep, net.touchcapture.qr.flutterqr, com.cloudwebrtc.webrtc, org.webrtc, com.it_nomads.fluttersecurestorage, com.pichillilorenzo.flutter_inappwebview, com.example.video_compress, com.otaliastudios.transcoder, com.otaliastudios.opengl, com.kineapps.flutter_file_dialog"/>
 | 
			
		||||
 | 
			
		||||
    <application
 | 
			
		||||
        android:name=".Application"
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,10 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
import 'package:matrix/matrix.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/utils/matrix_sdk_extensions.dart/event_extension.dart';
 | 
			
		||||
import 'package:fluffychat/utils/platform_infos.dart';
 | 
			
		||||
 | 
			
		||||
class MessageDownloadContent extends StatelessWidget {
 | 
			
		||||
  final Event event;
 | 
			
		||||
@ -28,24 +30,26 @@ class MessageDownloadContent extends StatelessWidget {
 | 
			
		||||
        crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
        mainAxisSize: MainAxisSize.min,
 | 
			
		||||
        children: <Widget>[
 | 
			
		||||
          Row(
 | 
			
		||||
            children: [
 | 
			
		||||
              Icon(
 | 
			
		||||
                Icons.file_download_outlined,
 | 
			
		||||
          ListTile(
 | 
			
		||||
            leading: Icon(
 | 
			
		||||
              Icons.file_download_outlined,
 | 
			
		||||
              color: textColor,
 | 
			
		||||
            ),
 | 
			
		||||
            title: Text(
 | 
			
		||||
              filename,
 | 
			
		||||
              maxLines: 1,
 | 
			
		||||
              style: TextStyle(
 | 
			
		||||
                color: textColor,
 | 
			
		||||
                fontWeight: FontWeight.bold,
 | 
			
		||||
              ),
 | 
			
		||||
              const SizedBox(width: 8),
 | 
			
		||||
              Expanded(
 | 
			
		||||
                child: Text(
 | 
			
		||||
                  filename,
 | 
			
		||||
                  maxLines: 1,
 | 
			
		||||
                  style: TextStyle(
 | 
			
		||||
                    color: textColor,
 | 
			
		||||
                    fontWeight: FontWeight.bold,
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
            ],
 | 
			
		||||
            ),
 | 
			
		||||
            trailing: PlatformInfos.isAndroid
 | 
			
		||||
                ? IconButton(
 | 
			
		||||
                    onPressed: () => event.shareFile(context),
 | 
			
		||||
                    tooltip: L10n.of(context)!.share,
 | 
			
		||||
                    icon: const Icon(Icons.share),
 | 
			
		||||
                  )
 | 
			
		||||
                : null,
 | 
			
		||||
          ),
 | 
			
		||||
          const Divider(),
 | 
			
		||||
          Row(
 | 
			
		||||
 | 
			
		||||
@ -28,6 +28,9 @@ class ImageViewerController extends State<ImageViewer> {
 | 
			
		||||
  /// Save this file with a system call.
 | 
			
		||||
  void saveFileAction() => widget.event.saveFile(context);
 | 
			
		||||
 | 
			
		||||
  /// Save this file with a system call.
 | 
			
		||||
  void shareFileAction() => widget.event.shareFile(context);
 | 
			
		||||
 | 
			
		||||
  static const maxScaleFactor = 1.5;
 | 
			
		||||
 | 
			
		||||
  /// Go back if user swiped it away
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:fluffychat/pages/chat/events/image_bubble.dart';
 | 
			
		||||
import 'package:fluffychat/utils/platform_infos.dart';
 | 
			
		||||
import 'image_viewer.dart';
 | 
			
		||||
 | 
			
		||||
class ImageViewerView extends StatelessWidget {
 | 
			
		||||
@ -37,6 +38,13 @@ class ImageViewerView extends StatelessWidget {
 | 
			
		||||
            color: Colors.white,
 | 
			
		||||
            tooltip: L10n.of(context)!.downloadFile,
 | 
			
		||||
          ),
 | 
			
		||||
          if (PlatformInfos.isAndroid)
 | 
			
		||||
            IconButton(
 | 
			
		||||
              onPressed: controller.shareFileAction,
 | 
			
		||||
              tooltip: L10n.of(context)!.share,
 | 
			
		||||
              color: Colors.white,
 | 
			
		||||
              icon: const Icon(Icons.share),
 | 
			
		||||
            )
 | 
			
		||||
        ],
 | 
			
		||||
      ),
 | 
			
		||||
      body: InteractiveViewer(
 | 
			
		||||
 | 
			
		||||
@ -8,18 +8,28 @@ import 'package:matrix/matrix.dart';
 | 
			
		||||
import 'matrix_file_extension.dart';
 | 
			
		||||
 | 
			
		||||
extension LocalizedBody on Event {
 | 
			
		||||
  Future<LoadingDialogResult<MatrixFile?>> _getFile(BuildContext context) =>
 | 
			
		||||
      showFutureLoadingDialog(
 | 
			
		||||
        context: context,
 | 
			
		||||
        future: () => downloadAndDecryptAttachmentCached(),
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
  void saveFile(BuildContext context) async {
 | 
			
		||||
    final matrixFile = await showFutureLoadingDialog(
 | 
			
		||||
      context: context,
 | 
			
		||||
      future: () => downloadAndDecryptAttachmentCached(),
 | 
			
		||||
    );
 | 
			
		||||
    final matrixFile = await _getFile(context);
 | 
			
		||||
 | 
			
		||||
    matrixFile.result?.save(context);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void shareFile(BuildContext context) async {
 | 
			
		||||
    final matrixFile = await _getFile(context);
 | 
			
		||||
 | 
			
		||||
    matrixFile.result?.share(context);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool get isAttachmentSmallEnough =>
 | 
			
		||||
      infoMap['size'] is int &&
 | 
			
		||||
      infoMap['size'] < room.client.database!.maxFileSize;
 | 
			
		||||
 | 
			
		||||
  bool get isThumbnailSmallEnough =>
 | 
			
		||||
      thumbnailInfoMap['size'] is int &&
 | 
			
		||||
      thumbnailInfoMap['size'] < room.client.database!.maxFileSize;
 | 
			
		||||
 | 
			
		||||
@ -13,23 +13,25 @@ import 'package:fluffychat/utils/platform_infos.dart';
 | 
			
		||||
extension MatrixFileExtension on MatrixFile {
 | 
			
		||||
  void save(BuildContext context) async {
 | 
			
		||||
    final fileName = name.split('/').last;
 | 
			
		||||
    if (PlatformInfos.isMobile) {
 | 
			
		||||
      final tmpDirectory = PlatformInfos.isAndroid
 | 
			
		||||
          ? (await getExternalStorageDirectories(
 | 
			
		||||
                  type: StorageDirectory.downloads))!
 | 
			
		||||
              .first
 | 
			
		||||
          : await getTemporaryDirectory();
 | 
			
		||||
      final path = '${tmpDirectory.path}$fileName';
 | 
			
		||||
      await File(path).writeAsBytes(bytes);
 | 
			
		||||
      await Share.shareFiles([path]);
 | 
			
		||||
      ScaffoldMessenger.of(context).showSnackBar(
 | 
			
		||||
        SnackBar(content: Text(L10n.of(context)!.savedFileAs(path))),
 | 
			
		||||
      );
 | 
			
		||||
      return;
 | 
			
		||||
    } else {
 | 
			
		||||
      final file = FilePickerCross(bytes);
 | 
			
		||||
      await file.exportToStorage(fileName: fileName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final file = FilePickerCross(bytes);
 | 
			
		||||
    await file.exportToStorage(fileName: fileName, share: false);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void share(BuildContext context) async {
 | 
			
		||||
    final fileName = name.split('/').last;
 | 
			
		||||
    final tmpDirectory = PlatformInfos.isAndroid
 | 
			
		||||
        ? (await getExternalStorageDirectories(
 | 
			
		||||
                type: StorageDirectory.downloads))!
 | 
			
		||||
            .first
 | 
			
		||||
        : await getTemporaryDirectory();
 | 
			
		||||
    final path = '${tmpDirectory.path}$fileName';
 | 
			
		||||
    await File(path).writeAsBytes(bytes);
 | 
			
		||||
    await Share.shareFiles([path]);
 | 
			
		||||
    ScaffoldMessenger.of(context).showSnackBar(
 | 
			
		||||
      SnackBar(content: Text(L10n.of(context)!.savedFileAs(path))),
 | 
			
		||||
    );
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  MatrixFile get detectFileType {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										96
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										96
									
								
								pubspec.lock
									
									
									
									
									
								
							@ -14,7 +14,7 @@ packages:
 | 
			
		||||
      name: adaptive_dialog
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.4.0"
 | 
			
		||||
    version: "1.6.1"
 | 
			
		||||
  adaptive_theme:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
@ -422,7 +422,7 @@ packages:
 | 
			
		||||
      name: file_picker_cross
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "4.5.0"
 | 
			
		||||
    version: "4.6.0"
 | 
			
		||||
  file_selector:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -437,13 +437,6 @@ packages:
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.0.2+1"
 | 
			
		||||
  file_selector_macos:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: file_selector_macos
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.0.4+1"
 | 
			
		||||
  file_selector_platform_interface:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -458,13 +451,6 @@ packages:
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.8.1+3"
 | 
			
		||||
  file_selector_windows:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: file_selector_windows
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.0.2+1"
 | 
			
		||||
  fluffybox:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -510,6 +496,13 @@ packages:
 | 
			
		||||
    description: flutter
 | 
			
		||||
    source: sdk
 | 
			
		||||
    version: "0.0.0"
 | 
			
		||||
  flutter_file_dialog:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: flutter_file_dialog
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.3.0"
 | 
			
		||||
  flutter_highlight:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -878,6 +871,13 @@ packages:
 | 
			
		||||
    description: flutter
 | 
			
		||||
    source: sdk
 | 
			
		||||
    version: "0.0.0"
 | 
			
		||||
  intersperse:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: intersperse
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.0.0"
 | 
			
		||||
  intl:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
@ -978,6 +978,13 @@ packages:
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.2.2"
 | 
			
		||||
  macos_ui:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: macos_ui
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.13.1"
 | 
			
		||||
  markdown:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -1106,27 +1113,20 @@ packages:
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.0.2"
 | 
			
		||||
  package_info:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: package_info
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.0.2"
 | 
			
		||||
  package_info_plus:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: package_info_plus
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.4.0"
 | 
			
		||||
    version: "1.4.2"
 | 
			
		||||
  package_info_plus_linux:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: package_info_plus_linux
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.0.3"
 | 
			
		||||
    version: "1.0.5"
 | 
			
		||||
  package_info_plus_macos:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -1147,14 +1147,14 @@ packages:
 | 
			
		||||
      name: package_info_plus_web
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.0.4"
 | 
			
		||||
    version: "1.0.5"
 | 
			
		||||
  package_info_plus_windows:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: package_info_plus_windows
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.0.4"
 | 
			
		||||
    version: "1.0.5"
 | 
			
		||||
  path:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@ -1456,6 +1456,48 @@ packages:
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.0.4"
 | 
			
		||||
  share_plus:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: share_plus
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "4.0.4"
 | 
			
		||||
  share_plus_linux:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: share_plus_linux
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.0.0"
 | 
			
		||||
  share_plus_macos:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: share_plus_macos
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.0.0"
 | 
			
		||||
  share_plus_platform_interface:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: share_plus_platform_interface
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.0.2"
 | 
			
		||||
  share_plus_web:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: share_plus_web
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.0.0"
 | 
			
		||||
  share_plus_windows:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: share_plus_windows
 | 
			
		||||
      url: "https://pub.dartlang.org"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.0.0"
 | 
			
		||||
  shared_preferences:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,7 @@ dependencies:
 | 
			
		||||
  emoji_picker_flutter: ^1.1.2
 | 
			
		||||
  encrypt: ^5.0.1
 | 
			
		||||
  #fcm_shared_isolate: ^0.1.0
 | 
			
		||||
  file_picker_cross: ^4.5.0
 | 
			
		||||
  file_picker_cross: ^4.6.0
 | 
			
		||||
  flutter:
 | 
			
		||||
    sdk: flutter
 | 
			
		||||
  flutter_app_badger: ^1.3.0
 | 
			
		||||
@ -152,4 +152,4 @@ dependency_overrides:
 | 
			
		||||
  snapping_sheet:
 | 
			
		||||
    git:
 | 
			
		||||
      url: https://github.com/TheOneWithTheBraid/snapping_sheet.git
 | 
			
		||||
      ref: listenable
 | 
			
		||||
      ref: listenable
 | 
			
		||||
@ -86,6 +86,6 @@ index c6295788..8dd17ce4 100644
 | 
			
		||||
   encrypt: ^5.0.1
 | 
			
		||||
-  #fcm_shared_isolate: ^0.1.0
 | 
			
		||||
+  fcm_shared_isolate: ^0.1.0
 | 
			
		||||
   file_picker_cross: ^4.5.0
 | 
			
		||||
   file_picker_cross: ^4.6.0
 | 
			
		||||
   flutter:
 | 
			
		||||
     sdk: flutter
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user