mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 09:08:40 +00:00
support gifs and allow videos to pick from the gallery
This commit is contained in:
parent
e1232f45b5
commit
9356a1fc70
7 changed files with 114 additions and 66 deletions
|
|
@ -161,13 +161,12 @@ class MediaFileService {
|
|||
return;
|
||||
}
|
||||
switch (mediaFile.type) {
|
||||
case MediaType.gif:
|
||||
case MediaType.image:
|
||||
// all images are already compress..
|
||||
break;
|
||||
case MediaType.video:
|
||||
await createThumbnailsForVideo(storedPath, thumbnailPath);
|
||||
case MediaType.gif:
|
||||
Log.error('Thumbnail for .gif is not implemented yet');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -183,8 +182,7 @@ class MediaFileService {
|
|||
case MediaType.video:
|
||||
await compressAndOverlayVideo(this);
|
||||
case MediaType.gif:
|
||||
originalPath.renameSync(tempPath.path);
|
||||
Log.error('Compression for .gif is not implemented yet.');
|
||||
originalPath.copySync(tempPath.path);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ class SaveToGalleryButtonState extends State<SaveToGalleryButton> {
|
|||
_imageSaving = true;
|
||||
});
|
||||
|
||||
if (widget.mediaService.mediaFile.type == MediaType.image) {
|
||||
if (widget.mediaService.mediaFile.type == MediaType.image ||
|
||||
widget.mediaService.mediaFile.type == MediaType.gif) {
|
||||
await widget.storeImageAsOriginal();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -285,9 +285,12 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
|||
Future<Uint8List?>? imageBytes,
|
||||
File? videoFilePath, {
|
||||
bool sharedFromGallery = false,
|
||||
MediaType? mediaType,
|
||||
}) async {
|
||||
final type = mediaType ??
|
||||
((videoFilePath != null) ? MediaType.video : MediaType.image);
|
||||
final mediaFileService = await initializeMediaUpload(
|
||||
(videoFilePath != null) ? MediaType.video : MediaType.image,
|
||||
type,
|
||||
gUser.defaultShowTime,
|
||||
);
|
||||
if (!mounted) return true;
|
||||
|
|
@ -377,14 +380,42 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
|||
_sharePreviewIsShown = true;
|
||||
});
|
||||
final picker = ImagePicker();
|
||||
final pickedFile = await picker.pickImage(source: ImageSource.gallery);
|
||||
final pickedFile = await picker.pickMedia();
|
||||
|
||||
if (pickedFile != null) {
|
||||
final imageFile = File(pickedFile.path);
|
||||
final imageExtensions = [
|
||||
'.png',
|
||||
'.jpg',
|
||||
'.jpeg',
|
||||
'.gif',
|
||||
'.webp',
|
||||
'.heic',
|
||||
'.heif',
|
||||
'.avif',
|
||||
];
|
||||
|
||||
Log.info('Picket from gallery: ${pickedFile.path}');
|
||||
|
||||
File? videoFilePath;
|
||||
Future<Uint8List>? imageBytes;
|
||||
MediaType? mediaType;
|
||||
|
||||
final isImage =
|
||||
imageExtensions.any((ext) => pickedFile.name.contains(ext));
|
||||
if (isImage) {
|
||||
if (pickedFile.name.contains('.gif')) {
|
||||
mediaType = MediaType.gif;
|
||||
}
|
||||
imageBytes = pickedFile.readAsBytes();
|
||||
} else {
|
||||
videoFilePath = File(pickedFile.path);
|
||||
}
|
||||
|
||||
await pushMediaEditor(
|
||||
imageFile.readAsBytes(),
|
||||
null,
|
||||
imageBytes,
|
||||
videoFilePath,
|
||||
sharedFromGallery: true,
|
||||
mediaType: mediaType,
|
||||
);
|
||||
}
|
||||
setState(() {
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
|||
double widthRatio = 1;
|
||||
double heightRatio = 1;
|
||||
double pixelRatio = 1;
|
||||
Uint8List? imageBytes;
|
||||
VideoPlayerController? videoController;
|
||||
ImageItem currentImage = ImageItem();
|
||||
ScreenshotController screenshotController = ScreenshotController();
|
||||
|
|
@ -66,13 +67,16 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
|||
void initState() {
|
||||
super.initState();
|
||||
|
||||
if (media.type != MediaType.gif) {
|
||||
layers.add(FilterLayerData());
|
||||
}
|
||||
|
||||
if (widget.sendToGroup != null) {
|
||||
selectedGroupIds.add(widget.sendToGroup!.groupId);
|
||||
}
|
||||
|
||||
if (widget.mediaFileService.mediaFile.type == MediaType.image) {
|
||||
if (widget.mediaFileService.mediaFile.type == MediaType.video ||
|
||||
widget.mediaFileService.mediaFile.type == MediaType.gif) {
|
||||
if (widget.imageBytesFuture != null) {
|
||||
loadImage(widget.imageBytesFuture!);
|
||||
} else {
|
||||
|
|
@ -124,6 +128,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
|||
return [];
|
||||
}
|
||||
return <Widget>[
|
||||
if (media.type != MediaType.gif)
|
||||
ActionButton(
|
||||
Icons.text_fields_rounded,
|
||||
tooltipText: context.lang.addTextItem,
|
||||
|
|
@ -141,6 +146,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
|||
},
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
if (media.type != MediaType.gif)
|
||||
ActionButton(
|
||||
Icons.draw_rounded,
|
||||
tooltipText: context.lang.addDrawing,
|
||||
|
|
@ -152,6 +158,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
|||
},
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
if (media.type != MediaType.gif)
|
||||
ActionButton(
|
||||
Icons.add_reaction_outlined,
|
||||
tooltipText: context.lang.addEmoji,
|
||||
|
|
@ -356,12 +363,18 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
|||
if (mediaService.tempPath.existsSync()) {
|
||||
mediaService.tempPath.deleteSync();
|
||||
}
|
||||
if (media.type == MediaType.gif) {
|
||||
mediaService.originalPath.writeAsBytesSync(imageBytes!.toList());
|
||||
} else {
|
||||
final imageBytes = await getEditedImageBytes();
|
||||
if (imageBytes == null) return false;
|
||||
if (media.type == MediaType.image) {
|
||||
if (media.type == MediaType.image || media.type == MediaType.gif) {
|
||||
mediaService.originalPath.writeAsBytesSync(imageBytes);
|
||||
} else {
|
||||
} else if (media.type == MediaType.video) {
|
||||
mediaService.overlayImagePath.writeAsBytesSync(imageBytes);
|
||||
} else {
|
||||
Log.error('MediaType not supported: ${media.type}');
|
||||
}
|
||||
}
|
||||
|
||||
// In case the image was already stored, then rename the stored image.
|
||||
|
|
@ -374,7 +387,8 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
|||
}
|
||||
|
||||
Future<void> loadImage(Future<Uint8List?> imageBytesFuture) async {
|
||||
await currentImage.load(await imageBytesFuture);
|
||||
imageBytes = await imageBytesFuture;
|
||||
await currentImage.load(imageBytes);
|
||||
if (isDisposed) return;
|
||||
|
||||
if (!context.mounted) return;
|
||||
|
|
|
|||
|
|
@ -298,7 +298,8 @@ class _MediaViewerViewState extends State<MediaViewerView> {
|
|||
if (gUser.storeMediaFilesInGallery) {
|
||||
if (currentMedia!.mediaFile.type == MediaType.video) {
|
||||
await saveVideoToGallery(currentMedia!.storedPath.path);
|
||||
} else if (currentMedia!.mediaFile.type == MediaType.image) {
|
||||
} else if (currentMedia!.mediaFile.type == MediaType.image ||
|
||||
currentMedia!.mediaFile.type == MediaType.gif) {
|
||||
final imageBytes = await currentMedia!.storedPath.readAsBytes();
|
||||
await saveImageToGallery(imageBytes);
|
||||
}
|
||||
|
|
@ -466,7 +467,8 @@ class _MediaViewerViewState extends State<MediaViewerView> {
|
|||
child: VideoPlayer(videoController!),
|
||||
),
|
||||
if (currentMedia != null &&
|
||||
currentMedia!.mediaFile.type == MediaType.image)
|
||||
currentMedia!.mediaFile.type == MediaType.image ||
|
||||
currentMedia!.mediaFile.type == MediaType.gif)
|
||||
Positioned.fill(
|
||||
child: Image.file(
|
||||
currentMedia!.tempPath,
|
||||
|
|
|
|||
|
|
@ -57,7 +57,8 @@ class _MemoriesItemThumbnailState extends State<MemoriesItemThumbnail> {
|
|||
if (media.thumbnailPath.existsSync())
|
||||
Image.file(media.thumbnailPath)
|
||||
else if (media.storedPath.existsSync() &&
|
||||
media.mediaFile.type == MediaType.image)
|
||||
media.mediaFile.type == MediaType.image ||
|
||||
media.mediaFile.type == MediaType.gif)
|
||||
Image.file(media.storedPath)
|
||||
else
|
||||
const Text('Media file removed.'),
|
||||
|
|
|
|||
|
|
@ -75,7 +75,8 @@ class _MemoriesPhotoSliderViewState extends State<MemoriesPhotoSliderView> {
|
|||
try {
|
||||
if (item.mediaFile.type == MediaType.video) {
|
||||
await saveVideoToGallery(item.storedPath.path);
|
||||
} else if (item.mediaFile.type == MediaType.image) {
|
||||
} else if (item.mediaFile.type == MediaType.image ||
|
||||
item.mediaFile.type == MediaType.gif) {
|
||||
final imageBytes = await item.storedPath.readAsBytes();
|
||||
await saveImageToGallery(imageBytes);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue