This commit is contained in:
otsmr 2025-05-29 00:33:08 +02:00
parent e7b48ecf63
commit 25d2edf89e
4 changed files with 75 additions and 23 deletions

View file

@ -91,11 +91,6 @@ Future retryMediaUpload({int maxRetries = 3}) async {
}
}
});
if (maxRetries == 0) return;
// retry upload
// Future.delayed(const Duration(milliseconds: 1000), () {
// retryMediaUpload(maxRetries: maxRetries - 1);
// });
}
Future<int?> initMediaUpload() async {
@ -576,7 +571,7 @@ Future<void> deleteMediaFile(int mediaUploadId, String type) async {
}
}
Future<String> getMediaFilePath(int mediaId, String type) async {
Future<String> getMediaFilePath(dynamic mediaId, String type) async {
final basedir = await getApplicationSupportDirectory();
final mediaSendDir = Directory(join(basedir.path, 'media', type));
if (!await mediaSendDir.exists()) {
@ -585,6 +580,15 @@ Future<String> getMediaFilePath(int mediaId, String type) async {
return join(mediaSendDir.path, '$mediaId');
}
Future<String> getMediaBaseFilePath(String type) async {
final basedir = await getApplicationSupportDirectory();
final mediaSendDir = Directory(join(basedir.path, 'media', type));
if (!await mediaSendDir.exists()) {
await mediaSendDir.create(recursive: true);
}
return mediaSendDir.path;
}
/// combines two utf8 list
Uint8List combineUint8Lists(Uint8List list1, Uint8List list2) {
final combinedLength = 4 + list1.length + list2.length;

View file

@ -1,6 +1,9 @@
import 'dart:io';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:path/path.dart';
import 'package:twonly/src/providers/api/media_send.dart';
import 'dart:typed_data';
import 'package:twonly/src/utils/misc.dart';
@ -9,11 +12,13 @@ class SaveToGalleryButton extends StatefulWidget {
final Future<Uint8List?> Function() getMergedImage;
final String? sendNextMediaToUserName;
final File? videoFilePath;
final int? mediaUploadId;
const SaveToGalleryButton(
{super.key,
required this.getMergedImage,
this.sendNextMediaToUserName,
this.mediaUploadId,
this.videoFilePath});
@override
@ -41,12 +46,26 @@ class SaveToGalleryButtonState extends State<SaveToGalleryButton> {
});
String? res;
String memoryPath = await getMediaBaseFilePath("memories");
if (widget.mediaUploadId != null) {
memoryPath = join(memoryPath, "${widget.mediaUploadId!}");
} else {
final Random random = Random();
String token = uint8ListToHex(
List<int>.generate(32, (i) => random.nextInt(256)));
memoryPath = join(memoryPath, token);
}
if (widget.videoFilePath != null) {
memoryPath += ".mp4";
await File(widget.videoFilePath!.path).copy(memoryPath);
res = await saveVideoToGallery(widget.videoFilePath!.path);
} else {
memoryPath += ".png";
Uint8List? imageBytes = await widget.getMergedImage();
if (imageBytes == null || !context.mounted) return;
await File(memoryPath).writeAsBytes(imageBytes);
res = await saveImageToGallery(imageBytes);
}
if (res == null) {

View file

@ -535,6 +535,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
children: [
SaveToGalleryButton(
getMergedImage: getMergedImage,
mediaUploadId: mediaUploadId,
videoFilePath: widget.videoFilePath,
sendNextMediaToUserName: sendNextMediaToUserName,
),

View file

@ -21,7 +21,7 @@ class GalleryItem {
this.imagePath,
this.videoPath,
});
final int id;
final String id;
final List<Message> messages;
final DateTime date;
final File? imagePath;
@ -135,6 +135,40 @@ class GalleryMainViewState extends State<GalleryMainView> {
initAsync();
}
Future<List<GalleryItem>> loadMemoriesDirectory() async {
final directoryPath = await send.getMediaBaseFilePath("memories");
final directory = Directory(directoryPath);
List<GalleryItem> items = [];
if (await directory.exists()) {
final files = directory.listSync();
for (var file in files) {
if (file is File) {
final fileName = file.uri.pathSegments.last;
File? imagePath;
File? videoPath;
if (fileName.contains(".png")) {
imagePath = file;
} else if (fileName.contains(".mp4")) {
videoPath = file;
} else {
break;
}
final creationDate = await file.lastModified();
items.add(GalleryItem(
id: fileName,
messages: [],
date: creationDate,
imagePath: imagePath,
videoPath: videoPath,
));
}
}
}
return items;
}
Future initAsync() async {
List<Message> storedMediaFiles =
await twonlyDatabase.messagesDao.getAllStoredMediaFiles();
@ -160,7 +194,7 @@ class GalleryMainViewState extends State<GalleryMainView> {
.putIfAbsent(
id,
() => GalleryItem(
id: id,
id: id.toString(),
messages: [],
date: message.sendAt,
imagePath: imagePath,
@ -174,7 +208,9 @@ class GalleryMainViewState extends State<GalleryMainView> {
months = [];
String lastMonth = "";
galleryItems = items.values.toList();
galleryItems = await loadMemoriesDirectory();
galleryItems += items.values.toList();
galleryItems.sort((a, b) => b.date.compareTo(a.date));
for (var i = 0; i < galleryItems.length; i++) {
String month = DateFormat('MMMM yyyy').format(galleryItems[i].date);
if (lastMonth != month) {
@ -232,9 +268,9 @@ class GalleryMainViewState extends State<GalleryMainView> {
MaterialPageRoute(
builder: (context) => GalleryPhotoViewWrapper(
galleryItems: galleryItems,
backgroundDecoration: const BoxDecoration(
color: Colors.black,
),
// backgroundDecoration: const BoxDecoration(
// color: Colors.black,
// ),
initialIndex: index,
scrollDirection: verticalGallery ? Axis.vertical : Axis.horizontal,
),
@ -298,12 +334,10 @@ class _GalleryPhotoViewWrapperState extends State<GalleryPhotoViewWrapper> {
FilledButton.icon(
icon: FaIcon(FontAwesomeIcons.solidPaperPlane),
onPressed: () async {
await Navigator.push(
Navigator.push(
context,
PageRouteBuilder(
opaque: false,
pageBuilder: (context, a1, a2) =>
ShareImageEditorView(
MaterialPageRoute(
builder: (context) => ShareImageEditorView(
videoFilePath:
widget.galleryItems[currentIndex].videoPath,
imageBytes: widget
@ -312,12 +346,6 @@ class _GalleryPhotoViewWrapperState extends State<GalleryPhotoViewWrapper> {
mirrorVideo: false,
useHighQuality: true,
),
transitionsBuilder:
(context, animation, secondaryAnimation, child) {
return child;
},
transitionDuration: Duration.zero,
reverseTransitionDuration: Duration.zero,
),
);
},