Compare commits

..

3 Commits

10 changed files with 57 additions and 48 deletions

View File

@ -3,7 +3,6 @@ import 'dart:io';
import 'package:cryptography/cryptography.dart';
import 'package:get_it/get_it.dart';
import 'package:hex/hex.dart';
import 'package:image_size_getter/image_size_getter.dart';
import 'package:logging/logging.dart';
import 'package:moxlib/moxlib.dart';
import 'package:moxxmpp/moxxmpp.dart';
@ -14,6 +13,7 @@ import 'package:moxxyv2/service/service.dart';
import 'package:moxxyv2/service/xmpp.dart';
import 'package:moxxyv2/shared/avatar.dart';
import 'package:moxxyv2/shared/events.dart';
import 'package:moxxyv2/shared/helpers.dart';
/// Removes line breaks and spaces from [original]. This might happen when we request the
/// avatar data. Returns the cleaned version.
@ -158,7 +158,7 @@ class AvatarService {
final public = prefs.isAvatarPublic;
// Read the image metadata
final imageSize = ImageSizeGetter.getSize(MemoryInput(bytes));
final imageSize = (await getImageSizeFromData(bytes))!;
// Publish data and metadata
final manager = _getUserAvatarManager();
@ -171,8 +171,8 @@ class AvatarService {
UserAvatarMetadata(
hash,
bytes.length,
imageSize.width,
imageSize.height,
imageSize.width.toInt(),
imageSize.height.toInt(),
// TODO(PapaTutuWawa): Maybe do a check here
'image/png',
),

View File

@ -6,8 +6,6 @@ import 'dart:math';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:dio/dio.dart' as dio;
import 'package:get_it/get_it.dart';
import 'package:image_size_getter/file_input.dart';
import 'package:image_size_getter/image_size_getter.dart';
import 'package:logging/logging.dart';
import 'package:mime/mime.dart';
import 'package:moxplatform/moxplatform.dart';
@ -24,6 +22,7 @@ import 'package:moxxyv2/service/notifications.dart';
import 'package:moxxyv2/service/service.dart';
import 'package:moxxyv2/shared/error_types.dart';
import 'package:moxxyv2/shared/events.dart';
import 'package:moxxyv2/shared/helpers.dart';
import 'package:moxxyv2/shared/warning_types.dart';
import 'package:path/path.dart' as pathlib;
import 'package:path_provider/path_provider.dart';
@ -438,16 +437,13 @@ class HttpFileTransferService {
MoxplatformPlugin.media.scanFile(downloadedPath);
// Find out the dimensions
// TODO(Unknown): Restrict to the library's supported file types
Size? size;
try {
size = ImageSizeGetter.getSize(FileInput(File(downloadedPath)));
} catch (ex) {
_log.warning('Failed to get image size for $downloadedPath: $ex');
final imageSize = await getImageSizeFromPath(downloadedPath);
if (imageSize == null) {
_log.warning('Failed to get image size for $downloadedPath');
}
mediaWidth = size?.width;
mediaHeight = size?.height;
mediaWidth = imageSize?.width.toInt();
mediaHeight = imageSize?.height.toInt();
} else if (mime.startsWith('video/')) {
// TODO(Unknown): Also figure out the thumbnail size here
MoxplatformPlugin.media.scanFile(downloadedPath);

View File

@ -3,8 +3,6 @@ import 'dart:io';
import 'dart:ui';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:get_it/get_it.dart';
import 'package:image_size_getter/file_input.dart';
import 'package:image_size_getter/image_size_getter.dart' as image_size;
import 'package:logging/logging.dart';
import 'package:mime/mime.dart';
import 'package:moxlib/moxlib.dart';
@ -375,13 +373,13 @@ class XmppService {
// TODO(Unknown): Do the same for videos
if (pathMime != null && pathMime.startsWith('image/')) {
try {
final imageSize = image_size.ImageSizeGetter.getSize(FileInput(File(path)));
final imageSize = await getImageSizeFromPath(path);
if (imageSize != null) {
dimensions[path] = Size(
imageSize.width.toDouble(),
imageSize.height.toDouble(),
imageSize.width,
imageSize.height,
);
} catch (ex) {
} else {
_log.warning('Failed to get image dimensions for $path');
}
}

View File

@ -1,4 +1,7 @@
import 'dart:core';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui';
import 'package:moxxyv2/i18n/strings.g.dart';
import 'package:moxxyv2/shared/models/message.dart';
import 'package:synchronized/synchronized.dart';
@ -317,3 +320,31 @@ String fileSizeToString(int size) {
return '$size B';
}
}
/// Load [path] into memory and determine its width and height. Returns null in case
/// of an error.
Future<Size?> getImageSizeFromPath(String path) async {
final bytes = await File(path).readAsBytes();
return getImageSizeFromData(bytes);
}
/// Like getImageSizeFromPath but taking the image's bytes directly.
Future<Size?> getImageSizeFromData(Uint8List bytes) async {
try {
final dartCodec = await instantiateImageCodec(bytes);
final dartFrame = await dartCodec.getNextFrame();
final size = Size(
dartFrame.image.width.toDouble(),
dartFrame.image.height.toDouble(),
);
dartFrame.image.dispose();
dartCodec.dispose();
return size;
} catch (_) {
// TODO(PapaTutuWawa): Log error
return null;
}
}

View File

@ -99,6 +99,9 @@ class Conversation with _$Conversation {
'lastMessage': lastMessage?.id,
};
}
/// True, when the chat state of the conversation indicates typing. False, if not.
bool get isTyping => chatState == ChatState.composing;
}
/// Sorts conversations in descending order by their last change timestamp.

View File

@ -5,7 +5,7 @@ import 'package:bloc/bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:get_it/get_it.dart';
import 'package:image/image.dart';
import 'package:image_size_getter/image_size_getter.dart';
import 'package:moxxyv2/shared/helpers.dart';
import 'package:moxxyv2/ui/bloc/navigation_bloc.dart';
import 'package:moxxyv2/ui/bloc/preferences_bloc.dart';
import 'package:moxxyv2/ui/constants.dart';
@ -81,13 +81,13 @@ class CropBackgroundBloc extends Bloc<CropBackgroundEvent, CropBackgroundState>
);
final data = await File(event.path).readAsBytes();
final imageSize = ImageSizeGetter.getSize(MemoryInput(data));
final imageSize = (await getImageSizeFromData(data))!;
emit(
state.copyWith(
image: data,
imagePath: event.path,
imageWidth: imageSize.width,
imageHeight: imageSize.height,
imageWidth: imageSize.width.toInt(),
imageHeight: imageSize.height.toInt(),
),
);
}

View File

@ -5,6 +5,7 @@ import 'package:moxxyv2/i18n/strings.g.dart';
import 'package:moxxyv2/ui/bloc/crop_bloc.dart';
import 'package:moxxyv2/ui/constants.dart';
import 'package:moxxyv2/ui/widgets/button.dart';
import 'package:moxxyv2/ui/widgets/cancel_button.dart';
class CropPage extends StatelessWidget {
CropPage({ super.key }) : _controller = CropController();
@ -42,11 +43,7 @@ class CropPage extends StatelessWidget {
top: 10,
child: Material(
color: const Color.fromRGBO(0, 0, 0, 0),
child: IconButton(
icon: const Icon(
Icons.arrow_back,
size: 32,
),
child: CancelButton(
onPressed: () => Navigator.of(context).pop(),
),
),

View File

@ -2,7 +2,6 @@ import 'dart:async';
import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:moxxmpp/moxxmpp.dart';
import 'package:moxxyv2/i18n/strings.g.dart';
import 'package:moxxyv2/shared/constants.dart';
import 'package:moxxyv2/shared/helpers.dart';
@ -82,7 +81,7 @@ class ConversationsListRowState extends State<ConversationsListRow> {
}
Widget _buildLastMessageBody() {
if (widget.conversation.chatState == ChatState.composing) {
if (widget.conversation.isTyping) {
return const TypingIndicatorWidget(Colors.black, Colors.white);
}
@ -198,7 +197,7 @@ class ConversationsListRowState extends State<ConversationsListRow> {
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
...widget.conversation.lastMessage?.isThumbnailable == true ? [
...widget.conversation.lastMessage?.isThumbnailable == true && !widget.conversation.isTyping ? [
Padding(
padding: const EdgeInsets.only(right: 5),
child: SharedImageWidget(

View File

@ -523,13 +523,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
hashcodes:
dependency: transitive
description:
name: hashcodes
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
hex:
dependency: "direct main"
description:
@ -558,13 +551,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.0"
image_size_getter:
dependency: "direct main"
description:
name: image_size_getter
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
integration_test:
dependency: "direct dev"
description: flutter

View File

@ -41,7 +41,6 @@ dependencies:
get_it: 7.2.0
hex: 0.2.0
image: 3.2.0
image_size_getter: 2.1.2
json_annotation: 4.6.0
logging: 1.0.2
mime: 1.0.2