mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-11-03 19:54:12 +00:00 
			
		
		
		
	Simplify conversation files appearance
This commit is contained in:
		@@ -1,46 +0,0 @@
 | 
				
			|||||||
import 'dart:io';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import 'package:comunic/models/conversation_message.dart';
 | 
					 | 
				
			||||||
import 'package:dio/dio.dart';
 | 
					 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					 | 
				
			||||||
import 'package:path/path.dart' as path;
 | 
					 | 
				
			||||||
import 'package:path_provider/path_provider.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Conversation files helper
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// @author Pierre Hubert
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ConversationFilesHelper {
 | 
					 | 
				
			||||||
  /// Get the path for chat file
 | 
					 | 
				
			||||||
  static Future<File> getPathForChatFile(
 | 
					 | 
				
			||||||
      int msgID, ConversationMessageFile fileInfo) async {
 | 
					 | 
				
			||||||
    Directory basePath = await getTemporaryDirectory();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    final storageDir = path.join(basePath.absolute.path, "conversation-files");
 | 
					 | 
				
			||||||
    final fileName = "$msgID";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return File(path.join(storageDir, fileName));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /// Download chat file
 | 
					 | 
				
			||||||
  static Future<void> download({
 | 
					 | 
				
			||||||
    @required int msgID,
 | 
					 | 
				
			||||||
    @required ConversationMessageFile fileInfo,
 | 
					 | 
				
			||||||
    @required Function(double) onProgress,
 | 
					 | 
				
			||||||
    @required CancelToken cancelToken,
 | 
					 | 
				
			||||||
  }) async {
 | 
					 | 
				
			||||||
    final target = await getPathForChatFile(msgID, fileInfo);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Create parent directory if required
 | 
					 | 
				
			||||||
    if (!await target.parent.exists()) {
 | 
					 | 
				
			||||||
      await target.parent.create(recursive: true);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    await Dio().download(
 | 
					 | 
				
			||||||
      fileInfo.url,
 | 
					 | 
				
			||||||
      target.path,
 | 
					 | 
				
			||||||
      cancelToken: cancelToken,
 | 
					 | 
				
			||||||
      onReceiveProgress: (p, t) => onProgress(p / fileInfo.size.toDouble()),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -78,8 +78,6 @@ class ConversationMessageFile {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  bool get hasThumbnail => thumbnail != null;
 | 
					  bool get hasThumbnail => thumbnail != null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool get downloadable => fileType == ConversationMessageFileType.AUDIO;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Map<String, dynamic> toJson() => {
 | 
					  Map<String, dynamic> toJson() => {
 | 
				
			||||||
        "url": url,
 | 
					        "url": url,
 | 
				
			||||||
        "size": size,
 | 
					        "size": size,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,19 +1,8 @@
 | 
				
			|||||||
/// Chat file tile
 | 
					/// Chat file tile
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// @author Pierre Hubert
 | 
					/// @author Pierre Hubert
 | 
				
			||||||
import 'dart:io';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import 'package:cached_network_image/cached_network_image.dart';
 | 
					 | 
				
			||||||
import 'package:comunic/helpers/conversation_files_helper.dart';
 | 
					 | 
				
			||||||
import 'package:comunic/models/conversation_message.dart';
 | 
					import 'package:comunic/models/conversation_message.dart';
 | 
				
			||||||
import 'package:comunic/ui/widgets/async_screen_widget.dart';
 | 
					 | 
				
			||||||
import 'package:comunic/ui/widgets/audio_player_widget.dart';
 | 
					 | 
				
			||||||
import 'package:comunic/ui/widgets/network_image_widget.dart';
 | 
					import 'package:comunic/ui/widgets/network_image_widget.dart';
 | 
				
			||||||
import 'package:comunic/utils/intl_utils.dart';
 | 
					 | 
				
			||||||
import 'package:comunic/utils/log_utils.dart';
 | 
					 | 
				
			||||||
import 'package:comunic/utils/ui_utils.dart';
 | 
					 | 
				
			||||||
import 'package:dio/dio.dart';
 | 
					 | 
				
			||||||
import 'package:filesize/filesize.dart';
 | 
					 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:url_launcher/url_launcher.dart';
 | 
					import 'package:url_launcher/url_launcher.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -36,131 +25,13 @@ class ConversationFileWidget extends StatefulWidget {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _ConversationFileWidgetState extends State<ConversationFileWidget> {
 | 
					class _ConversationFileWidgetState extends State<ConversationFileWidget> {
 | 
				
			||||||
  final _refreshKey = GlobalKey<AsyncScreenWidgetState>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  File _targetFile;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  bool _isDownloaded;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  bool _downloading = false;
 | 
					 | 
				
			||||||
  var _downloadProgress = 0.0;
 | 
					 | 
				
			||||||
  CancelToken _cancelDownloadToken;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ConversationMessageFile get file => widget.file;
 | 
					  ConversationMessageFile get file => widget.file;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<void> _refresh() async {
 | 
					 | 
				
			||||||
    _targetFile = await ConversationFilesHelper.getPathForChatFile(
 | 
					 | 
				
			||||||
        widget.messageID, file);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    _isDownloaded = await _targetFile.exists();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) =>
 | 
				
			||||||
    return Container(
 | 
					      Container(width: _AreaSize, height: _AreaSize, child: _buildContent());
 | 
				
			||||||
      width: _AreaSize,
 | 
					 | 
				
			||||||
      height: _AreaSize,
 | 
					 | 
				
			||||||
      child: AsyncScreenWidget(
 | 
					 | 
				
			||||||
        key: _refreshKey,
 | 
					 | 
				
			||||||
        onReload: _refresh,
 | 
					 | 
				
			||||||
        onBuild: _buildContent,
 | 
					 | 
				
			||||||
        errorMessage: tr("Error!"),
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Widget _buildContent() => _isDownloaded || !file.downloadable
 | 
					  Widget _buildContent() {
 | 
				
			||||||
      ? _buildFileWidget()
 | 
					 | 
				
			||||||
      : _buildDownloadWidget();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Widget _buildDownloadWidget() => Stack(
 | 
					 | 
				
			||||||
        children: <Widget>[
 | 
					 | 
				
			||||||
          // Thumbnail, if possible
 | 
					 | 
				
			||||||
          !file.hasThumbnail
 | 
					 | 
				
			||||||
              ? Container()
 | 
					 | 
				
			||||||
              : CachedNetworkImage(
 | 
					 | 
				
			||||||
                  imageUrl: file.thumbnail,
 | 
					 | 
				
			||||||
                  width: _AreaSize,
 | 
					 | 
				
			||||||
                  height: _AreaSize,
 | 
					 | 
				
			||||||
                  fit: BoxFit.fill,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          Container(
 | 
					 | 
				
			||||||
            width: _AreaSize,
 | 
					 | 
				
			||||||
            color: Color(0x66000000),
 | 
					 | 
				
			||||||
            child: DefaultTextStyle(
 | 
					 | 
				
			||||||
              style: TextStyle(color: Colors.white),
 | 
					 | 
				
			||||||
              child: Column(
 | 
					 | 
				
			||||||
                children: <Widget>[
 | 
					 | 
				
			||||||
                  Spacer(),
 | 
					 | 
				
			||||||
                  Icon(file.icon, color: Colors.white),
 | 
					 | 
				
			||||||
                  Spacer(),
 | 
					 | 
				
			||||||
                  _buildDownloadArea(),
 | 
					 | 
				
			||||||
                  Spacer(),
 | 
					 | 
				
			||||||
                  Text(filesize(file.size)),
 | 
					 | 
				
			||||||
                  Spacer(),
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
          )
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Widget _buildDownloadArea() => _downloading
 | 
					 | 
				
			||||||
      ? _buildDownloadingWidget()
 | 
					 | 
				
			||||||
      : Material(
 | 
					 | 
				
			||||||
          borderRadius: BorderRadius.all(Radius.circular(2.0)),
 | 
					 | 
				
			||||||
          color: Colors.green,
 | 
					 | 
				
			||||||
          child: IconButton(
 | 
					 | 
				
			||||||
            icon: Icon(Icons.file_download),
 | 
					 | 
				
			||||||
            onPressed: _downloadFile,
 | 
					 | 
				
			||||||
            color: Colors.white,
 | 
					 | 
				
			||||||
          ),
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Widget _buildDownloadingWidget() => Container(
 | 
					 | 
				
			||||||
        width: 36,
 | 
					 | 
				
			||||||
        height: 36,
 | 
					 | 
				
			||||||
        child: Stack(
 | 
					 | 
				
			||||||
          children: <Widget>[
 | 
					 | 
				
			||||||
            CircularProgressIndicator(value: _downloadProgress),
 | 
					 | 
				
			||||||
            Center(
 | 
					 | 
				
			||||||
              child: InkWell(
 | 
					 | 
				
			||||||
                onTap: () => _cancelDownloadToken.cancel(),
 | 
					 | 
				
			||||||
                child: Icon(Icons.cancel, color: Colors.white),
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
          ],
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Future<void> _downloadFile() async {
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      setState(() {
 | 
					 | 
				
			||||||
        _cancelDownloadToken = CancelToken();
 | 
					 | 
				
			||||||
        _downloading = true;
 | 
					 | 
				
			||||||
        _downloadProgress = 0.0;
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      await ConversationFilesHelper.download(
 | 
					 | 
				
			||||||
        msgID: widget.messageID,
 | 
					 | 
				
			||||||
        fileInfo: file,
 | 
					 | 
				
			||||||
        onProgress: (p) => setState(() => _downloadProgress = p),
 | 
					 | 
				
			||||||
        cancelToken: _cancelDownloadToken,
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      await _refreshKey.currentState.refresh();
 | 
					 | 
				
			||||||
    } catch (e, s) {
 | 
					 | 
				
			||||||
      logError(e, s);
 | 
					 | 
				
			||||||
      showSimpleSnack(context, tr("Failed to download file!"));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    setState(() {
 | 
					 | 
				
			||||||
      _downloading = false;
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Widget _buildFileWidget() {
 | 
					 | 
				
			||||||
    switch (file.fileType) {
 | 
					    switch (file.fileType) {
 | 
				
			||||||
      // Images
 | 
					      // Images
 | 
				
			||||||
      case ConversationMessageFileType.IMAGE:
 | 
					      case ConversationMessageFileType.IMAGE:
 | 
				
			||||||
@@ -172,10 +43,6 @@ class _ConversationFileWidgetState extends State<ConversationFileWidget> {
 | 
				
			|||||||
          ),
 | 
					          ),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Audio player
 | 
					 | 
				
			||||||
      case ConversationMessageFileType.AUDIO:
 | 
					 | 
				
			||||||
        return AudioPlayerWidget(_targetFile);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // The file is not downloadable, we open it in the browser
 | 
					      // The file is not downloadable, we open it in the browser
 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
        return Center(
 | 
					        return Center(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,13 +22,6 @@ packages:
 | 
				
			|||||||
      url: "https://pub.dartlang.org"
 | 
					      url: "https://pub.dartlang.org"
 | 
				
			||||||
    source: hosted
 | 
					    source: hosted
 | 
				
			||||||
    version: "2.5.0-nullsafety.1"
 | 
					    version: "2.5.0-nullsafety.1"
 | 
				
			||||||
  audioplayers:
 | 
					 | 
				
			||||||
    dependency: "direct main"
 | 
					 | 
				
			||||||
    description:
 | 
					 | 
				
			||||||
      name: audioplayers
 | 
					 | 
				
			||||||
      url: "https://pub.dartlang.org"
 | 
					 | 
				
			||||||
    source: hosted
 | 
					 | 
				
			||||||
    version: "0.15.1"
 | 
					 | 
				
			||||||
  boolean_selector:
 | 
					  boolean_selector:
 | 
				
			||||||
    dependency: transitive
 | 
					    dependency: transitive
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -91,9 +91,6 @@ dependencies:
 | 
				
			|||||||
  # Version manager
 | 
					  # Version manager
 | 
				
			||||||
  version: ^1.2.0
 | 
					  version: ^1.2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Play audio files
 | 
					 | 
				
			||||||
  audioplayers: ^0.15.1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  # Get path to temporary files
 | 
					  # Get path to temporary files
 | 
				
			||||||
  path_provider: ^1.6.27
 | 
					  path_provider: ^1.6.27
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user