Compare commits
3 commits
main
...
mobile-vid
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fae54faffc | ||
![]() |
d4f781bf35 | ||
![]() |
9c4e72aa0f |
|
@ -43,7 +43,7 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
applicationId "io.ente.photos"
|
||||
minSdkVersion 21
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 33
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
|
|
BIN
mobile/android/app/src/dev/res/mipmap-hdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
mobile/android/app/src/dev/res/mipmap-mdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
mobile/android/app/src/dev/res/mipmap-xhdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
mobile/android/app/src/dev/res/mipmap-xxhdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
mobile/android/app/src/dev/res/mipmap-xxxhdpi/launcher_icon.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
mobile/assets/launcher_icon/ente-icon-dev.png
Normal file
After Width: | Height: | Size: 1 MiB |
4
mobile/flutter_launcher_icons-dev.yaml
Normal file
|
@ -0,0 +1,4 @@
|
|||
flutter_launcher_icons:
|
||||
android: "launcher_icon"
|
||||
ios: true
|
||||
image_path: "assets/launcher_icon/ente-icon-dev.png"
|
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 6 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 9.2 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 5.6 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 30 KiB |
|
@ -0,0 +1 @@
|
|||
{"images":[{"size":"20x20","idiom":"iphone","filename":"AppIcon-dev-20x20@2x.png","scale":"2x"},{"size":"20x20","idiom":"iphone","filename":"AppIcon-dev-20x20@3x.png","scale":"3x"},{"size":"29x29","idiom":"iphone","filename":"AppIcon-dev-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"iphone","filename":"AppIcon-dev-29x29@2x.png","scale":"2x"},{"size":"29x29","idiom":"iphone","filename":"AppIcon-dev-29x29@3x.png","scale":"3x"},{"size":"40x40","idiom":"iphone","filename":"AppIcon-dev-40x40@2x.png","scale":"2x"},{"size":"40x40","idiom":"iphone","filename":"AppIcon-dev-40x40@3x.png","scale":"3x"},{"size":"50x50","idiom":"ipad","filename":"AppIcon-dev-50x50@1x.png","scale":"1x"},{"size":"50x50","idiom":"ipad","filename":"AppIcon-dev-50x50@2x.png","scale":"2x"},{"size":"57x57","idiom":"iphone","filename":"AppIcon-dev-57x57@1x.png","scale":"1x"},{"size":"57x57","idiom":"iphone","filename":"AppIcon-dev-57x57@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"AppIcon-dev-60x60@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"AppIcon-dev-60x60@3x.png","scale":"3x"},{"size":"20x20","idiom":"ipad","filename":"AppIcon-dev-20x20@1x.png","scale":"1x"},{"size":"20x20","idiom":"ipad","filename":"AppIcon-dev-20x20@2x.png","scale":"2x"},{"size":"29x29","idiom":"ipad","filename":"AppIcon-dev-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"ipad","filename":"AppIcon-dev-29x29@2x.png","scale":"2x"},{"size":"40x40","idiom":"ipad","filename":"AppIcon-dev-40x40@1x.png","scale":"1x"},{"size":"40x40","idiom":"ipad","filename":"AppIcon-dev-40x40@2x.png","scale":"2x"},{"size":"72x72","idiom":"ipad","filename":"AppIcon-dev-72x72@1x.png","scale":"1x"},{"size":"72x72","idiom":"ipad","filename":"AppIcon-dev-72x72@2x.png","scale":"2x"},{"size":"76x76","idiom":"ipad","filename":"AppIcon-dev-76x76@1x.png","scale":"1x"},{"size":"76x76","idiom":"ipad","filename":"AppIcon-dev-76x76@2x.png","scale":"2x"},{"size":"83.5x83.5","idiom":"ipad","filename":"AppIcon-dev-83.5x83.5@2x.png","scale":"2x"},{"size":"1024x1024","idiom":"ios-marketing","filename":"AppIcon-dev-1024x1024@1x.png","scale":"1x"}],"info":{"version":1,"author":"xcode"}}
|
|
@ -123,9 +123,8 @@ Future<void> _runBackgroundTask(String taskId, {String mode = 'normal'}) async {
|
|||
if (_isProcessRunning) {
|
||||
_logger.info("Background task triggered when process was already running");
|
||||
await _sync('bgTaskActiveProcess');
|
||||
BackgroundFetch.finish(taskId);
|
||||
BackgroundFetch.finish(taskId).ignore();
|
||||
} else {
|
||||
// ignore: unawaited_futures
|
||||
_runWithLogs(
|
||||
() async {
|
||||
_logger.info("Starting background task in $mode mode");
|
||||
|
@ -133,7 +132,7 @@ Future<void> _runBackgroundTask(String taskId, {String mode = 'normal'}) async {
|
|||
_runInBackground(taskId);
|
||||
},
|
||||
prefix: "[bg]",
|
||||
);
|
||||
).ignore();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,7 +140,7 @@ Future<void> _runInBackground(String taskId) async {
|
|||
await Future.delayed(const Duration(seconds: 3));
|
||||
if (await _isRunningInForeground()) {
|
||||
_logger.info("FG task running, skipping BG taskID: $taskId");
|
||||
BackgroundFetch.finish(taskId);
|
||||
BackgroundFetch.finish(taskId).ignore();
|
||||
return;
|
||||
} else {
|
||||
_logger.info("FG task is not running");
|
||||
|
@ -161,7 +160,7 @@ Future<void> _runInBackground(String taskId) async {
|
|||
}(),
|
||||
],
|
||||
);
|
||||
BackgroundFetch.finish(taskId);
|
||||
BackgroundFetch.finish(taskId).ignore();
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/73796478/546896
|
||||
|
@ -334,7 +333,7 @@ Future<void> _killBGTask([String? taskId]) async {
|
|||
|
||||
await prefs.remove(kLastBGTaskHeartBeatTime);
|
||||
if (taskId != null) {
|
||||
BackgroundFetch.finish(taskId);
|
||||
BackgroundFetch.finish(taskId).ignore();
|
||||
}
|
||||
|
||||
///Band aid for background process not getting killed. Should migrate to using
|
||||
|
|
177
mobile/lib/ui/tools/editor/crop_video_page.dart
Normal file
|
@ -0,0 +1,177 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:fraction/fraction.dart';
|
||||
import 'package:video_editor/video_editor.dart';
|
||||
|
||||
class CropPage extends StatelessWidget {
|
||||
const CropPage({super.key, required this.controller});
|
||||
|
||||
final VideoEditorController controller;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.black,
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 30),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: IconButton(
|
||||
onPressed: () =>
|
||||
controller.rotate90Degrees(RotateDirection.left),
|
||||
icon: const Icon(Icons.rotate_left),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: IconButton(
|
||||
onPressed: () =>
|
||||
controller.rotate90Degrees(RotateDirection.right),
|
||||
icon: const Icon(Icons.rotate_right),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
Expanded(
|
||||
child: CropGridViewer.edit(
|
||||
controller: controller,
|
||||
rotateCropArea: false,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 20),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: IconButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
icon: const Center(
|
||||
child: Text(
|
||||
"cancel",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: AnimatedBuilder(
|
||||
animation: controller,
|
||||
builder: (_, __) => Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () =>
|
||||
controller.preferredCropAspectRatio =
|
||||
controller.preferredCropAspectRatio
|
||||
?.toFraction()
|
||||
.inverse()
|
||||
.toDouble(),
|
||||
icon: controller.preferredCropAspectRatio !=
|
||||
null &&
|
||||
controller.preferredCropAspectRatio! < 1
|
||||
? const Icon(
|
||||
Icons.panorama_vertical_select_rounded,
|
||||
)
|
||||
: const Icon(
|
||||
Icons.panorama_vertical_rounded,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () =>
|
||||
controller.preferredCropAspectRatio =
|
||||
controller.preferredCropAspectRatio
|
||||
?.toFraction()
|
||||
.inverse()
|
||||
.toDouble(),
|
||||
icon: controller.preferredCropAspectRatio !=
|
||||
null &&
|
||||
controller.preferredCropAspectRatio! > 1
|
||||
? const Icon(
|
||||
Icons
|
||||
.panorama_horizontal_select_rounded,
|
||||
)
|
||||
: const Icon(
|
||||
Icons.panorama_horizontal_rounded,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
_buildCropButton(context, null),
|
||||
_buildCropButton(context, 1.toFraction()),
|
||||
_buildCropButton(
|
||||
context,
|
||||
Fraction.fromString("9/16"),
|
||||
),
|
||||
_buildCropButton(
|
||||
context,
|
||||
Fraction.fromString("3/4"),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
// WAY 1: validate crop parameters set in the crop view
|
||||
controller.applyCacheCrop();
|
||||
// WAY 2: update manually with Offset values
|
||||
// controller.updateCrop(const Offset(0.2, 0.2), const Offset(0.8, 0.8));
|
||||
Navigator.pop(context);
|
||||
},
|
||||
icon: Center(
|
||||
child: Text(
|
||||
"done",
|
||||
style: TextStyle(
|
||||
color:
|
||||
const CropGridStyle().selectedBoundariesColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCropButton(BuildContext context, Fraction? f) {
|
||||
if (controller.preferredCropAspectRatio != null &&
|
||||
controller.preferredCropAspectRatio! > 1) f = f?.inverse();
|
||||
|
||||
return Flexible(
|
||||
child: TextButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 0,
|
||||
backgroundColor: controller.preferredCropAspectRatio == f?.toDouble()
|
||||
? Colors.grey.shade800
|
||||
: null,
|
||||
foregroundColor: controller.preferredCropAspectRatio == f?.toDouble()
|
||||
? Colors.white
|
||||
: null,
|
||||
textStyle: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
onPressed: () => controller.preferredCropAspectRatio = f?.toDouble(),
|
||||
child: Text(f == null ? 'free' : '${f.numerator}:${f.denominator}'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
199
mobile/lib/ui/tools/editor/export_video_result.dart
Normal file
|
@ -0,0 +1,199 @@
|
|||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fraction/fraction.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
||||
Future<void> _getImageDimension(
|
||||
File file, {
|
||||
required Function(Size) onResult,
|
||||
}) async {
|
||||
final decodedImage = await decodeImageFromList(file.readAsBytesSync());
|
||||
onResult(Size(decodedImage.width.toDouble(), decodedImage.height.toDouble()));
|
||||
}
|
||||
|
||||
String _fileMBSize(File file) =>
|
||||
' ${(file.lengthSync() / (1024 * 1024)).toStringAsFixed(1)} MB';
|
||||
|
||||
class VideoResultPopup extends StatefulWidget {
|
||||
const VideoResultPopup({super.key, required this.video});
|
||||
|
||||
final File video;
|
||||
|
||||
@override
|
||||
State<VideoResultPopup> createState() => _VideoResultPopupState();
|
||||
}
|
||||
|
||||
class _VideoResultPopupState extends State<VideoResultPopup> {
|
||||
VideoPlayerController? _controller;
|
||||
FileImage? _fileImage;
|
||||
Size _fileDimension = Size.zero;
|
||||
late final bool _isGif =
|
||||
path.extension(widget.video.path).toLowerCase() == ".gif";
|
||||
late String _fileMbSize;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (_isGif) {
|
||||
_getImageDimension(
|
||||
widget.video,
|
||||
onResult: (d) => setState(() => _fileDimension = d),
|
||||
);
|
||||
} else {
|
||||
_controller = VideoPlayerController.file(widget.video);
|
||||
_controller?.initialize().then((_) {
|
||||
_fileDimension = _controller?.value.size ?? Size.zero;
|
||||
setState(() {});
|
||||
_controller?.play();
|
||||
_controller?.setLooping(true);
|
||||
});
|
||||
}
|
||||
_fileMbSize = _fileMBSize(widget.video);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
if (_isGif) {
|
||||
_fileImage?.evict();
|
||||
} else {
|
||||
_controller?.pause();
|
||||
_controller?.dispose();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(30),
|
||||
child: Center(
|
||||
child: Stack(
|
||||
alignment: Alignment.bottomLeft,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: _fileDimension.aspectRatio == 0
|
||||
? 1
|
||||
: _fileDimension.aspectRatio,
|
||||
child:
|
||||
_isGif ? Image.file(widget.video) : VideoPlayer(_controller!),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
child: FileDescription(
|
||||
description: {
|
||||
'Video path': widget.video.path,
|
||||
if (!_isGif)
|
||||
'Video duration':
|
||||
'${((_controller?.value.duration.inMilliseconds ?? 0) / 1000).toStringAsFixed(2)}s',
|
||||
'Video ratio': Fraction.fromDouble(_fileDimension.aspectRatio)
|
||||
.reduce()
|
||||
.toString(),
|
||||
'Video dimension': _fileDimension.toString(),
|
||||
'Video size': _fileMbSize,
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CoverResultPopup extends StatefulWidget {
|
||||
const CoverResultPopup({super.key, required this.cover});
|
||||
|
||||
final File cover;
|
||||
|
||||
@override
|
||||
State<CoverResultPopup> createState() => _CoverResultPopupState();
|
||||
}
|
||||
|
||||
class _CoverResultPopupState extends State<CoverResultPopup> {
|
||||
late final Uint8List _imagebytes = widget.cover.readAsBytesSync();
|
||||
Size? _fileDimension;
|
||||
late String _fileMbSize;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_getImageDimension(
|
||||
widget.cover,
|
||||
onResult: (d) => setState(() => _fileDimension = d),
|
||||
);
|
||||
_fileMbSize = _fileMBSize(widget.cover);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(30),
|
||||
child: Center(
|
||||
child: Stack(
|
||||
children: [
|
||||
Image.memory(_imagebytes),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
child: FileDescription(
|
||||
description: {
|
||||
'Cover path': widget.cover.path,
|
||||
'Cover ratio':
|
||||
Fraction.fromDouble(_fileDimension?.aspectRatio ?? 0)
|
||||
.reduce()
|
||||
.toString(),
|
||||
'Cover dimension': _fileDimension.toString(),
|
||||
'Cover size': _fileMbSize,
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FileDescription extends StatelessWidget {
|
||||
const FileDescription({super.key, required this.description});
|
||||
|
||||
final Map<String, String> description;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DefaultTextStyle(
|
||||
style: const TextStyle(fontSize: 11),
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width - 60,
|
||||
padding: const EdgeInsets.all(10),
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: description.entries
|
||||
.map(
|
||||
(entry) => Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '${entry.key}: ',
|
||||
style: const TextStyle(fontSize: 11),
|
||||
),
|
||||
TextSpan(
|
||||
text: entry.value,
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
color: Colors.white.withOpacity(0.8),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
49
mobile/lib/ui/tools/editor/export_video_service.dart
Normal file
|
@ -0,0 +1,49 @@
|
|||
import 'dart:developer';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:ffmpeg_kit_flutter_min/ffmpeg_kit.dart';
|
||||
import 'package:ffmpeg_kit_flutter_min/ffmpeg_kit_config.dart';
|
||||
import 'package:ffmpeg_kit_flutter_min/ffmpeg_session.dart';
|
||||
import 'package:ffmpeg_kit_flutter_min/return_code.dart';
|
||||
import 'package:ffmpeg_kit_flutter_min/statistics.dart';
|
||||
import 'package:video_editor/video_editor.dart';
|
||||
|
||||
class ExportService {
|
||||
static Future<void> dispose() async {
|
||||
final executions = await FFmpegKit.listSessions();
|
||||
if (executions.isNotEmpty) await FFmpegKit.cancel();
|
||||
}
|
||||
|
||||
static Future<FFmpegSession> runFFmpegCommand(
|
||||
FFmpegVideoEditorExecute execute, {
|
||||
required void Function(File file) onCompleted,
|
||||
void Function(Object, StackTrace)? onError,
|
||||
void Function(Statistics)? onProgress,
|
||||
}) {
|
||||
log('FFmpeg start process with command = ${execute.command}');
|
||||
return FFmpegKit.executeAsync(
|
||||
execute.command,
|
||||
(session) async {
|
||||
final state =
|
||||
FFmpegKitConfig.sessionStateToString(await session.getState());
|
||||
final code = await session.getReturnCode();
|
||||
|
||||
if (ReturnCode.isSuccess(code)) {
|
||||
onCompleted(File(execute.outputPath));
|
||||
} else {
|
||||
if (onError != null) {
|
||||
onError(
|
||||
Exception(
|
||||
'FFmpeg process exited with state $state and return code $code.\n${await session.getOutput()}',
|
||||
),
|
||||
StackTrace.current,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
},
|
||||
null,
|
||||
onProgress,
|
||||
);
|
||||
}
|
||||
}
|
367
mobile/lib/ui/tools/editor/video_editor_page.dart
Normal file
|
@ -0,0 +1,367 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import "package:photos/models/file/file.dart";
|
||||
import 'package:photos/ui/tools/editor/crop_video_page.dart';
|
||||
import 'package:photos/ui/tools/editor/export_video_result.dart';
|
||||
import 'package:photos/ui/tools/editor/export_video_service.dart';
|
||||
import "package:photos/ui/viewer/file/detail_page.dart";
|
||||
import "package:video_editor/video_editor.dart";
|
||||
|
||||
class VideoEditorPage extends StatefulWidget {
|
||||
const VideoEditorPage({
|
||||
super.key,
|
||||
required this.file,
|
||||
required this.ioFile,
|
||||
required this.detailPageConfig,
|
||||
});
|
||||
|
||||
final EnteFile file;
|
||||
final File ioFile;
|
||||
final DetailPageConfiguration detailPageConfig;
|
||||
|
||||
@override
|
||||
State<VideoEditorPage> createState() => _VideoEditorPageState();
|
||||
}
|
||||
|
||||
class _VideoEditorPageState extends State<VideoEditorPage> {
|
||||
final _exportingProgress = ValueNotifier<double>(0.0);
|
||||
final _isExporting = ValueNotifier<bool>(false);
|
||||
final double height = 60;
|
||||
|
||||
late final VideoEditorController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = VideoEditorController.file(
|
||||
widget.ioFile,
|
||||
minDuration: const Duration(seconds: 1),
|
||||
);
|
||||
_controller.initialize().then((_) => setState(() {})).catchError(
|
||||
(error) {
|
||||
// handle minumum duration bigger than video duration error
|
||||
Navigator.pop(context);
|
||||
},
|
||||
test: (e) => e is VideoMinDurationError,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() async {
|
||||
_exportingProgress.dispose();
|
||||
_isExporting.dispose();
|
||||
_controller.dispose().ignore();
|
||||
ExportService.dispose().ignore();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _showErrorSnackBar(String message) =>
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(message),
|
||||
duration: const Duration(seconds: 1),
|
||||
),
|
||||
);
|
||||
|
||||
void _exportVideo() async {
|
||||
_exportingProgress.value = 0;
|
||||
_isExporting.value = true;
|
||||
|
||||
final config = VideoFFmpegVideoEditorConfig(
|
||||
_controller,
|
||||
// format: VideoExportFormat.gif,
|
||||
// commandBuilder: (config, videoPath, outputPath) {
|
||||
// final List<String> filters = config.getExportFilters();
|
||||
// filters.add('hflip'); // add horizontal flip
|
||||
|
||||
// return '-i $videoPath ${config.filtersCmd(filters)} -preset ultrafast $outputPath';
|
||||
// },
|
||||
);
|
||||
|
||||
await ExportService.runFFmpegCommand(
|
||||
await config.getExecuteConfig(),
|
||||
onProgress: (stats) {
|
||||
_exportingProgress.value =
|
||||
config.getFFmpegProgress(stats.getTime().toInt());
|
||||
},
|
||||
onError: (e, s) => _showErrorSnackBar("Error on export video :("),
|
||||
onCompleted: (file) {
|
||||
_isExporting.value = false;
|
||||
if (!mounted) return;
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => VideoResultPopup(video: file),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _exportCover() async {
|
||||
final config = CoverFFmpegVideoEditorConfig(_controller);
|
||||
final execute = await config.getExecuteConfig();
|
||||
if (execute == null) {
|
||||
_showErrorSnackBar("Error on cover exportation initialization.");
|
||||
return;
|
||||
}
|
||||
|
||||
await ExportService.runFFmpegCommand(
|
||||
execute,
|
||||
onError: (e, s) => _showErrorSnackBar("Error on cover exportation :("),
|
||||
onCompleted: (cover) {
|
||||
if (!mounted) return;
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => CoverResultPopup(cover: cover),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WillPopScope(
|
||||
onWillPop: () async => false,
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.black,
|
||||
body: _controller.initialized
|
||||
? SafeArea(
|
||||
child: Stack(
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
_topNavBar(),
|
||||
Expanded(
|
||||
child: DefaultTabController(
|
||||
length: 2,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
physics:
|
||||
const NeverScrollableScrollPhysics(),
|
||||
children: [
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
CropGridViewer.preview(
|
||||
controller: _controller,
|
||||
),
|
||||
AnimatedBuilder(
|
||||
animation: _controller.video,
|
||||
builder: (_, __) => AnimatedOpacity(
|
||||
opacity:
|
||||
_controller.isPlaying ? 0 : 1,
|
||||
duration: kThemeAnimationDuration,
|
||||
child: GestureDetector(
|
||||
onTap: _controller.video.play,
|
||||
child: Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration:
|
||||
const BoxDecoration(
|
||||
color: Colors.white,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.play_arrow,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
CoverViewer(controller: _controller),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 200,
|
||||
margin: const EdgeInsets.only(top: 10),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: _trimSlider(),
|
||||
),
|
||||
),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: _isExporting,
|
||||
builder: (_, bool export, Widget? child) =>
|
||||
AnimatedSize(
|
||||
duration: kThemeAnimationDuration,
|
||||
child: export ? child : null,
|
||||
),
|
||||
child: AlertDialog(
|
||||
title: ValueListenableBuilder(
|
||||
valueListenable: _exportingProgress,
|
||||
builder: (_, double value, __) => Text(
|
||||
"Exporting video ${(value * 100).ceil()}%",
|
||||
style: const TextStyle(fontSize: 12),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: const Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _topNavBar() {
|
||||
return SafeArea(
|
||||
child: SizedBox(
|
||||
height: height,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: IconButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
icon: const Icon(Icons.exit_to_app),
|
||||
tooltip: 'Leave editor',
|
||||
),
|
||||
),
|
||||
const VerticalDivider(endIndent: 22, indent: 22),
|
||||
Expanded(
|
||||
child: IconButton(
|
||||
onPressed: () =>
|
||||
_controller.rotate90Degrees(RotateDirection.left),
|
||||
icon: const Icon(Icons.rotate_left),
|
||||
tooltip: 'Rotate unclockwise',
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: IconButton(
|
||||
onPressed: () =>
|
||||
_controller.rotate90Degrees(RotateDirection.right),
|
||||
icon: const Icon(Icons.rotate_right),
|
||||
tooltip: 'Rotate clockwise',
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: IconButton(
|
||||
onPressed: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute<void>(
|
||||
builder: (context) => CropPage(controller: _controller),
|
||||
),
|
||||
),
|
||||
icon: const Icon(Icons.crop),
|
||||
tooltip: 'Open crop screen',
|
||||
),
|
||||
),
|
||||
const VerticalDivider(endIndent: 22, indent: 22),
|
||||
Expanded(
|
||||
child: PopupMenuButton(
|
||||
tooltip: 'Open export menu',
|
||||
icon: const Icon(Icons.save),
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(
|
||||
onTap: _exportCover,
|
||||
child: const Text('Export cover'),
|
||||
),
|
||||
PopupMenuItem(
|
||||
onTap: _exportVideo,
|
||||
child: const Text('Export video'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String formatter(Duration duration) => [
|
||||
duration.inMinutes.remainder(60).toString().padLeft(2, '0'),
|
||||
duration.inSeconds.remainder(60).toString().padLeft(2, '0'),
|
||||
].join(":");
|
||||
|
||||
List<Widget> _trimSlider() {
|
||||
return [
|
||||
AnimatedBuilder(
|
||||
animation: Listenable.merge([
|
||||
_controller,
|
||||
_controller.video,
|
||||
]),
|
||||
builder: (_, __) {
|
||||
final int duration = _controller.videoDuration.inSeconds;
|
||||
final double pos = _controller.trimPosition * duration;
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: height / 4),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(formatter(Duration(seconds: pos.toInt()))),
|
||||
const Expanded(child: SizedBox()),
|
||||
AnimatedOpacity(
|
||||
opacity: _controller.isTrimming ? 1 : 0,
|
||||
duration: kThemeAnimationDuration,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(formatter(_controller.startTrim)),
|
||||
const SizedBox(width: 10),
|
||||
Text(formatter(_controller.endTrim)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
margin: EdgeInsets.symmetric(vertical: height / 4),
|
||||
child: TrimSlider(
|
||||
controller: _controller,
|
||||
height: height,
|
||||
horizontalMargin: height / 4,
|
||||
child: TrimTimeline(
|
||||
controller: _controller,
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
Widget _coverSelection() {
|
||||
return SingleChildScrollView(
|
||||
child: Center(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.all(15),
|
||||
child: CoverSelection(
|
||||
controller: _controller,
|
||||
size: height + 10,
|
||||
quantity: 8,
|
||||
selectedCoverBuilder: (cover, size) {
|
||||
return Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
cover,
|
||||
Icon(
|
||||
Icons.check_circle,
|
||||
color: const CoverSelectionStyle().selectedBorderColor,
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ import 'package:photos/models/file/file.dart';
|
|||
import "package:photos/models/file/file_type.dart";
|
||||
import "package:photos/ui/common/fast_scroll_physics.dart";
|
||||
import 'package:photos/ui/tools/editor/image_editor_page.dart';
|
||||
import "package:photos/ui/tools/editor/video_editor_page.dart";
|
||||
import "package:photos/ui/viewer/file/file_app_bar.dart";
|
||||
import "package:photos/ui/viewer/file/file_bottom_bar.dart";
|
||||
import 'package:photos/ui/viewer/file/file_widget.dart';
|
||||
|
@ -370,6 +371,21 @@ class _DetailPageState extends State<DetailPage> {
|
|||
await dialog.hide();
|
||||
return;
|
||||
}
|
||||
if (file.fileType == FileType.video) {
|
||||
await dialog.hide();
|
||||
replacePage(
|
||||
context,
|
||||
VideoEditorPage(
|
||||
file: file,
|
||||
ioFile: ioFile,
|
||||
detailPageConfig: widget.config.copyWith(
|
||||
files: _files,
|
||||
selectedIndex: _selectedIndexNotifier.value,
|
||||
),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
final imageProvider =
|
||||
ExtendedFileImageProvider(ioFile, cacheRawData: true);
|
||||
await precacheImage(imageProvider, context);
|
||||
|
|
|
@ -85,7 +85,8 @@ class FileBottomBarState extends State<FileBottomBar> {
|
|||
|
||||
if (!widget.showOnlyInfoButton && widget.file is! TrashFile) {
|
||||
if (widget.file.fileType == FileType.image ||
|
||||
widget.file.fileType == FileType.livePhoto) {
|
||||
widget.file.fileType == FileType.livePhoto ||
|
||||
widget.file.fileType == FileType.video) {
|
||||
children.add(
|
||||
Tooltip(
|
||||
message: "Edit",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:archive/archive_io.dart';
|
||||
import "package:cross_file/cross_file.dart";
|
||||
import 'package:email_validator/email_validator.dart';
|
||||
import "package:file_saver/file_saver.dart";
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
@ -133,7 +132,7 @@ Future<String> getZippedLogsFile(BuildContext context) async {
|
|||
final encoder = ZipFileEncoder();
|
||||
encoder.create(zipFilePath);
|
||||
await encoder.addDirectory(logsDirectory);
|
||||
encoder.close();
|
||||
encoder.close().ignore();
|
||||
await dialog.hide();
|
||||
return zipFilePath;
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@ Future<void> _computeZip(Map<String, dynamic> args) async {
|
|||
encoder.create(zipPath);
|
||||
await encoder.addFile(File(imagePath), "image" + extension(imagePath));
|
||||
await encoder.addFile(File(videoPath), "video" + extension(videoPath));
|
||||
encoder.close();
|
||||
encoder.close().ignore();
|
||||
}
|
||||
|
||||
Future<void> zip({
|
||||
|
|
|
@ -5,18 +5,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a
|
||||
sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "61.0.0"
|
||||
version: "67.0.0"
|
||||
_flutterfire_internals:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _flutterfire_internals
|
||||
sha256: "0cb43f83f36ba8cb20502dee0c205e3f3aafb751732d724aeac3f2e044212cc2"
|
||||
sha256: "2350805d7afefb0efe7acd325cb19d3ae8ba4039b906eade3807ffb69938a01f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.29"
|
||||
version: "1.3.33"
|
||||
adaptive_theme:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -29,10 +29,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562
|
||||
sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.13.0"
|
||||
version: "6.4.1"
|
||||
animate_do:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -69,10 +69,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: archive
|
||||
sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d"
|
||||
sha256: ecf4273855368121b1caed0d10d4513c7241dfc813f7d3c8933b36622ae9b265
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.10"
|
||||
version: "3.5.1"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -93,10 +93,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: background_fetch
|
||||
sha256: dbffec0317ccdef6e2014cb543e147f52441e29c4fcb53dfd23558c4d92ddece
|
||||
sha256: "2fe367c9be0e256dadb75b8b637b0b58a2a2d2317b7c8420bb1ae8b41e23fde3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.2"
|
||||
version: "1.3.4"
|
||||
battery_info:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -205,10 +205,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: cached_network_image_web
|
||||
sha256: "42a835caa27c220d1294311ac409a43361088625a4f23c820b006dd9bffb3316"
|
||||
sha256: "205d6a9f1862de34b93184f22b9d2d94586b2f05c581d546695e3d8f6a805cd7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.2.0"
|
||||
cast:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -295,10 +295,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: connectivity_plus
|
||||
sha256: ebe15d94de9dd7c31dc2ac54e42780acdf3384b1497c69290c9f3c5b0279fc57
|
||||
sha256: db7a4e143dc72cc3cb2044ef9b052a7ebfe729513e6a82943bc3526f784365b8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.2"
|
||||
version: "6.0.3"
|
||||
connectivity_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -319,10 +319,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76"
|
||||
sha256: "3945034e86ea203af7a056d98e98e42a5518fff200d6e8e6647e1886b07e936e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.7.2"
|
||||
version: "1.8.0"
|
||||
cross_file:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -359,10 +359,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55"
|
||||
sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
version: "2.3.6"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -544,6 +544,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
ffmpeg_kit_flutter_min:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: ffmpeg_kit_flutter_min
|
||||
sha256: "123bfbc0e0b9e7cf6d32d8ba8e08b666d66af0f52c07683dd2305fbfc13f494a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.3"
|
||||
ffmpeg_kit_flutter_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffmpeg_kit_flutter_platform_interface
|
||||
sha256: addf046ae44e190ad0101b2fde2ad909a3cd08a2a109f6106d2f7048b7abedee
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1"
|
||||
figma_squircle:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -569,14 +585,46 @@ packages:
|
|||
url: "https://github.com/jesims/file_saver.git"
|
||||
source: git
|
||||
version: "0.2.9"
|
||||
file_selector_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_linux
|
||||
sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.2+1"
|
||||
file_selector_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_macos
|
||||
sha256: f42eacb83b318e183b1ae24eead1373ab1334084404c8c16e0354f9a3e55d385
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.4"
|
||||
file_selector_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_platform_interface
|
||||
sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.2"
|
||||
file_selector_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_windows
|
||||
sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.3+1"
|
||||
firebase_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_core
|
||||
sha256: "6b1152a5af3b1cfe7e45309e96fc1aa14873f410f7aadb3878aa7812acfa7531"
|
||||
sha256: "372d94ced114b9c40cb85e18c50ac94a7e998c8eec630c50d7aec047847d27bf"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.30.0"
|
||||
version: "2.31.0"
|
||||
firebase_core_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -589,34 +637,34 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_web
|
||||
sha256: c8b02226e548f35aace298e2bb2e6c24e34e8a203d614e742bb1146e5a4ad3c8
|
||||
sha256: "43d9e951ac52b87ae9cc38ecdcca1e8fa7b52a1dd26a96085ba41ce5108db8e9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.15.0"
|
||||
version: "2.17.0"
|
||||
firebase_messaging:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_messaging
|
||||
sha256: "87e3eda0ecdfeadb5fd1cf0dc5153aea5307a0cfca751c4b1ac97bfdd805660e"
|
||||
sha256: e0882a7426821f7caccaabfc15a535155cd15b4daa73a5a7b3af701a552d73ab
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.8.1"
|
||||
version: "14.9.2"
|
||||
firebase_messaging_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_messaging_platform_interface
|
||||
sha256: "80b4ccf20066b0579ebc88d4678230a5f53ab282fe040e31671af745db1588f9"
|
||||
sha256: "52e12cc50e1395ad7ea3552dcbe9958fb1994b5afcf58ee4c0db053932a6fce5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.5.31"
|
||||
version: "4.5.35"
|
||||
firebase_messaging_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_messaging_web
|
||||
sha256: "9224aa4db1ce6f08d96a82978453d37e9980204a20e410a11d9b774b24c6841c"
|
||||
sha256: "8812cc5929380b783f92290d934bf32e2fea06701583f47cdccd5f13f4f24522"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.8.1"
|
||||
version: "3.8.5"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -727,10 +775,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_local_notifications
|
||||
sha256: f9a05409385b77b06c18f200a41c7c2711ebf7415669350bb0f8474c07bd40d1
|
||||
sha256: "40e6fbd2da7dcc7ed78432c5cdab1559674b4af035fddbfb2f9a8f9c2112fcef"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "17.0.0"
|
||||
version: "17.1.2"
|
||||
flutter_local_notifications_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -743,10 +791,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: flutter_local_notifications_platform_interface
|
||||
sha256: "7cf643d6d5022f3baed0be777b0662cce5919c0a7b86e700299f22dc4ae660ef"
|
||||
sha256: "340abf67df238f7f0ef58f4a26d2a83e1ab74c77ab03cd2b2d5018ac64db30b7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0+1"
|
||||
version: "7.1.0"
|
||||
flutter_localizations:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
@ -780,10 +828,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_native_splash
|
||||
sha256: "558f10070f03ee71f850a78f7136ab239a67636a294a44a06b6b7345178edb1e"
|
||||
sha256: edf39bcf4d74aca1eb2c1e43c3e445fd9f494013df7f0da752fefe72020eedc0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.10"
|
||||
version: "2.4.0"
|
||||
flutter_password_strength:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -812,34 +860,34 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_linux
|
||||
sha256: "3d5032e314774ee0e1a7d0a9f5e2793486f0dff2dd9ef5a23f4e3fb2a0ae6a9e"
|
||||
sha256: "4d91bfc23047422cbcd73ac684bc169859ee766482517c22172c86596bf1464b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
flutter_secure_storage_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_macos
|
||||
sha256: bd33935b4b628abd0b86c8ca20655c5b36275c3a3f5194769a7b3f37c905369c
|
||||
sha256: b768a7dab26d6186b68e2831b3104f8968154f0f4fdbf66e7c2dd7bdf299daaf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.1.1"
|
||||
flutter_secure_storage_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_platform_interface
|
||||
sha256: "0d4d3a5dd4db28c96ae414d7ba3b8422fd735a8255642774803b2532c9a61d7e"
|
||||
sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "1.1.2"
|
||||
flutter_secure_storage_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_web
|
||||
sha256: "30f84f102df9dcdaa2241866a958c2ec976902ebdaa8883fbfe525f1f2f3cf20"
|
||||
sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "1.2.1"
|
||||
flutter_secure_storage_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -894,10 +942,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: fluttertoast
|
||||
sha256: dfdde255317af381bfc1c486ed968d5a43a2ded9c931e87cbecd88767d6a71c1
|
||||
sha256: "81b68579e23fcbcada2db3d50302813d2371664afe6165bc78148050ab94bf66"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.2.4"
|
||||
version: "8.2.5"
|
||||
fraction:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: fraction
|
||||
sha256: "09e9504c9177bbd77df56e5d147abfbb3b43360e64bf61510059c14d6a82d524"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.2"
|
||||
freezed:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
@ -1027,66 +1083,130 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: image_editor
|
||||
sha256: "6401a431ef1e988e35a8b19ff02cb7d31bd881fd7db0d39261ac8236683ef1c1"
|
||||
sha256: "0fe70befea0dbaf24a7cacc32c28311a65118f66637997ad072e9063f59efdd8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
version: "1.5.1"
|
||||
image_editor_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_editor_common
|
||||
sha256: "07fc9bcc16918a8230e132b9d9a9f66bb1cef3ac99f5e2939cf2ad7a6775b511"
|
||||
sha256: d141c0847148a7da573a5be5ca02e70d381e61cb6484ebef52a230ca1d6c56ab
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.1.2"
|
||||
image_editor_ohos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_editor_ohos
|
||||
sha256: aee8fa1490fedbb98583dfaebb4162c295abeb0044e94f2eb2ad52ae419e6f6e
|
||||
sha256: "06756859586d5acefec6e3b4f356f9b1ce05ef09213bcb9a0ce1680ecea2d054"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.7"
|
||||
version: "0.0.9"
|
||||
image_editor_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_editor_platform_interface
|
||||
sha256: ee01ec5e228e10c40f96d7f822c176d4140c15b6706e4a701866ee0cdd1c2b72
|
||||
sha256: "474517efc770464f7d99942472d8cfb369a3c378e95466ec17f74d2b80bd40de"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.1.0"
|
||||
image_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: image_picker
|
||||
sha256: "33974eca2e87e8b4e3727f1b94fa3abcb25afe80b6bc2c4d449a0e150aedf720"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
image_picker_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_android
|
||||
sha256: "0f57fee1e8bfadf8cc41818bbcd7f72e53bb768a54d9496355d5e8a5681a19f1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.12+1"
|
||||
image_picker_for_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_for_web
|
||||
sha256: "5d6eb13048cd47b60dbf1a5495424dea226c5faf3950e20bf8120a58efb5b5f3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.4"
|
||||
image_picker_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_ios
|
||||
sha256: "4824d8c7f6f89121ef0122ff79bb00b009607faecc8545b86bca9ab5ce1e95bf"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.11+2"
|
||||
image_picker_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_linux
|
||||
sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1+1"
|
||||
image_picker_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_macos
|
||||
sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1+1"
|
||||
image_picker_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_platform_interface
|
||||
sha256: "9ec26d410ff46f483c5519c29c02ef0e02e13a543f882b152d4bfd2f06802f80"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.10.0"
|
||||
image_picker_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_windows
|
||||
sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1+1"
|
||||
in_app_purchase:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: in_app_purchase
|
||||
sha256: def70fbaa2a274f4d835677459f6f7afc5469de912438f86076e51cbd4cbd5b4
|
||||
sha256: "960f26a08d9351fb8f89f08901f8a829d41b04d45a694b8f776121d9e41dcad6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.13"
|
||||
version: "3.2.0"
|
||||
in_app_purchase_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: in_app_purchase_android
|
||||
sha256: b9d4ecf70c51ab46222502c050b1535f6249caf9d768c4abd856ea16a18a882d
|
||||
sha256: bc4e58e8bd9f1027ca869f419737773bdf80ad36074037fa8ed81e5ca15dc655
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.3+1"
|
||||
version: "0.3.5+1"
|
||||
in_app_purchase_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: in_app_purchase_platform_interface
|
||||
sha256: "412efce2b9238c5ace4f057acad43f793ed06880e366d26ae322e796cadb051a"
|
||||
sha256: "1d353d38251da5b9fea6635c0ebfc6bb17a2d28d0e86ea5e083bf64244f1fb4c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.7"
|
||||
version: "1.4.0"
|
||||
in_app_purchase_storekit:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: in_app_purchase_storekit
|
||||
sha256: e0f860e760488dbd666e0f27e239d128cba744607fc62434dc76c19d1c292439
|
||||
sha256: "3eea5e173fca0a59ab2fcec5201bea14bb808dfad01004d2b1d7bfdb9244c5e6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.13+1"
|
||||
version: "0.3.16"
|
||||
integration_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
@ -1120,18 +1240,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: json_annotation
|
||||
sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
|
||||
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.8.1"
|
||||
version: "4.9.0"
|
||||
json_serializable:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: json_serializable
|
||||
sha256: aa1f5a8912615733e0fdc7a02af03308933c93235bdc8d50d0b0c8a8ccb0b969
|
||||
sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.7.1"
|
||||
version: "6.8.0"
|
||||
latlong2:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1208,18 +1328,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: local_auth_android
|
||||
sha256: "3bcd732dda7c75fcb7ddaef12e131230f53dcc8c00790d0d6efb3aa0fbbeda57"
|
||||
sha256: e0e5b1ea247c5a0951c13a7ee13dc1beae69750e6a2e1910d1ed6a3cd4d56943
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.37"
|
||||
version: "1.0.38"
|
||||
local_auth_darwin:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: local_auth_darwin
|
||||
sha256: "33381a15b0de2279523eca694089393bb146baebdce72a404555d03174ebc1e9"
|
||||
sha256: "959145a4cf6f0de745b9ec9ac60101270eb4c5b8b7c2a0470907014adc1c618d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
version: "1.3.0"
|
||||
local_auth_ios:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1384,10 +1504,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: modal_bottom_sheet
|
||||
sha256: "3bba63c62d35c931bce7f8ae23a47f9a05836d8cb3c11122ada64e0b2f3d718f"
|
||||
sha256: eac66ef8cb0461bf069a38c5eb0fa728cee525a531a8304bd3f7b2185407c67e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0-pre"
|
||||
version: "3.0.0"
|
||||
motion_photos:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1555,10 +1675,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
|
||||
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
version: "2.4.0"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1603,10 +1723,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_android
|
||||
sha256: "1acac6bae58144b442f11e66621c062aead9c99841093c38f5bcdcc24c1c3474"
|
||||
sha256: "8bb852cd759488893805c3161d0b2b5db55db52f773dbb014420b304055ba2c5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "12.0.5"
|
||||
version: "12.0.6"
|
||||
permission_handler_apple:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1651,10 +1771,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: photo_manager
|
||||
sha256: df594f989f0c31cdb3ed48f3d49cb9ffadf11cc3700d2c3460b1912c93432621
|
||||
sha256: "1ddee48659025df5c80153a2e85c3fa0f5b5733ecffcda9769a9447da2c51352"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
version: "3.1.1"
|
||||
photo_manager_image_provider:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1699,10 +1819,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: pointycastle
|
||||
sha256: "70fe966348fe08c34bf929582f1d8247d9d9408130723206472b4687227e4333"
|
||||
sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.8.0"
|
||||
version: "3.9.1"
|
||||
polylabel:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1779,10 +1899,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: receive_sharing_intent
|
||||
sha256: fe02f858ac9f8d44d62e1964dadded000bb48dea424085ed280d542a61c4e8ba
|
||||
sha256: f127989f8662ea15e193bd1e10605e5a0ab6bb92dffd51f3ce002feb0ce24c93
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
version: "1.8.0"
|
||||
rxdart:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1859,18 +1979,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: sentry
|
||||
sha256: fe99a06970b909a491b7f89d54c9b5119772e3a48a400308a6e129625b333f5b
|
||||
sha256: "57514bc72d441ffdc463f498d6886aa586a2494fa467a1eb9d649c28010d7ee3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.19.0"
|
||||
version: "7.20.2"
|
||||
sentry_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sentry_flutter
|
||||
sha256: fc013d4a753447320f62989b1871fdc1f20c77befcc8be3e38774dd7402e7a62
|
||||
sha256: "9723d58470ca43a360681ddd26abb71ca7b815f706bc8d3747afd054cf639ded"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.19.0"
|
||||
version: "7.20.2"
|
||||
share_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1907,10 +2027,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_foundation
|
||||
sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
|
||||
sha256: "0a8a893bf4fd1152f93fec03a415d11c27c74454d96e2318a7ac38dd18683ab7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.5"
|
||||
version: "2.4.0"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -2032,18 +2152,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: sqflite
|
||||
sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6
|
||||
sha256: a43e5a27235518c03ca238e7b4732cf35eabe863a369ceba6cbefa537a66f16d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
version: "2.3.3+1"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_common
|
||||
sha256: "28d8c66baee4968519fb8bd6cdbedad982d6e53359091f0b74544a9f32ec72d5"
|
||||
sha256: "3da423ce7baf868be70e2c0976c28a1bb2f73644268b7ffa7d2e08eab71f16a4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.3"
|
||||
version: "2.5.4"
|
||||
sqflite_migration:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -2056,18 +2176,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: sqlite3
|
||||
sha256: "072128763f1547e3e9b4735ce846bfd226d68019ccda54db4cd427b12dfdedc9"
|
||||
sha256: b384f598b813b347c5a7e5ffad82cbaff1bec3d1561af267041e66f6f0899295
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.4.3"
|
||||
sqlite3_flutter_libs:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sqlite3_flutter_libs
|
||||
sha256: d6c31c8511c441d1f12f20b607343df1afe4eddf24a1cf85021677c8eea26060
|
||||
sha256: fb2a106a2ea6042fe57de2c47074cc31539a941819c91e105b864744605da3f5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.20"
|
||||
version: "0.5.21"
|
||||
sqlite_async:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -2192,10 +2312,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: timezone
|
||||
sha256: "1cfd8ddc2d1cfd836bc93e67b9be88c3adaeca6f40a00ca999104c30693cdca0"
|
||||
sha256: a6ccda4a69a442098b602c44e61a1e2b4bf6f5516e875bbf0f427d5df14745d5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.2"
|
||||
version: "0.9.3"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -2204,6 +2324,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
transparent_image:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: transparent_image
|
||||
sha256: e8991d955a2094e197ca24c645efec2faf4285772a4746126ca12875e54ca02f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
tuple:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -2296,10 +2424,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_ios
|
||||
sha256: "9149d493b075ed740901f3ee844a38a00b33116c7c5c10d7fb27df8987fb51d5"
|
||||
sha256: "7068716403343f6ba4969b4173cbf3b84fc768042124bc2c011e5d782b24fe89"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.5"
|
||||
version: "6.3.0"
|
||||
url_launcher_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -2312,10 +2440,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_macos
|
||||
sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234
|
||||
sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
version: "3.2.0"
|
||||
url_launcher_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -2328,10 +2456,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_web
|
||||
sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d"
|
||||
sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
version: "2.3.1"
|
||||
url_launcher_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -2356,6 +2484,15 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
video_editor:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: HEAD
|
||||
resolved-ref: "1eeb18e2b1ce36bd8ca70178c0d4b485e9982257"
|
||||
url: "https://github.com/prateekmedia/video_editor.git"
|
||||
source: git
|
||||
version: "3.0.0"
|
||||
video_player:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -2369,18 +2506,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: video_player_android
|
||||
sha256: "821cff3446bbde255e8d03c12fe1f9810c69fee2c26c394545b13d824ba63c2e"
|
||||
sha256: "134e1ad410d67e18a19486ed9512c72dfc6d8ffb284d0e8f2e99e903d1ba8fa3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.13"
|
||||
version: "2.4.14"
|
||||
video_player_avfoundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player_avfoundation
|
||||
sha256: "00c49b1d68071341397cf760b982c1e26ed9232464c8506ee08378a5cca5070d"
|
||||
sha256: d1e9a824f2b324000dc8fb2dcb2a3285b6c1c7c487521c63306cc5b394f68a7c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.7"
|
||||
version: "2.6.1"
|
||||
video_player_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -2393,10 +2530,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: video_player_web
|
||||
sha256: "34beb3a07d4331a24f7e7b2f75b8e2b103289038e07e65529699a671b6a6e2cb"
|
||||
sha256: "41245cef5ef29c4585dbabcbcbe9b209e34376642c7576cabf11b4ad9289d6e4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
version: "2.3.0"
|
||||
video_thumbnail:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -2433,18 +2570,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: wakelock_plus
|
||||
sha256: f268ca2116db22e57577fb99d52515a24bdc1d570f12ac18bb762361d43b043d
|
||||
sha256: "104d94837bb28c735894dcd592877e990149c380e6358b00c04398ca1426eed4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.4"
|
||||
version: "1.2.1"
|
||||
wakelock_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: wakelock_plus_platform_interface
|
||||
sha256: "40fabed5da06caff0796dc638e1f07ee395fb18801fbff3255a2372db2d80385"
|
||||
sha256: "422d1cdbb448079a8a62a5a770b69baa489f8f7ca21aef47800c726d404f9d16"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.1"
|
||||
wallpaper_manager_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -2473,10 +2610,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
|
||||
sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.4.5"
|
||||
webdriver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -2505,26 +2642,26 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: widgets_to_image
|
||||
sha256: e32c7b77267c01d319dc97333d4f3d894e9d81c8b3a408fd33862fa7775ee398
|
||||
sha256: ed97b986af380a7eb9662b727d7ac610c3862c50bdc950346deea7a7eba12a84
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.2"
|
||||
version: "0.0.3"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
|
||||
sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.2.0"
|
||||
version: "5.5.0"
|
||||
win32_registry:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32_registry
|
||||
sha256: "41fd8a189940d8696b1b810efb9abcf60827b6cbfab90b0c43e8439e3a39d85a"
|
||||
sha256: "10589e0d7f4e053f2c61023a31c9ce01146656a70b7b7f0828c0b46d7da2a9bb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "1.1.3"
|
||||
wkt_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -12,7 +12,7 @@ description: ente photos application
|
|||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
|
||||
version: 0.8.96+616
|
||||
version: 0.8.98+618
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
|
@ -61,6 +61,7 @@ dependencies:
|
|||
extended_image: ^8.1.1
|
||||
fade_indexed_stack: ^0.2.2
|
||||
fast_base58: ^0.2.1
|
||||
ffmpeg_kit_flutter_min: ^6.0.3
|
||||
figma_squircle: ^0.5.3
|
||||
file_saver:
|
||||
# Use forked version till this PR is merged: https://github.com/incrediblezayed/file_saver/pull/87
|
||||
|
@ -90,6 +91,7 @@ dependencies:
|
|||
flutter_sodium: ^0.2.0
|
||||
flutter_staggered_grid_view: ^0.6.2
|
||||
fluttertoast: ^8.0.6
|
||||
fraction: ^5.0.2
|
||||
freezed_annotation: ^2.4.1
|
||||
google_nav_bar: ^5.0.5
|
||||
home_widget: ^0.5.0
|
||||
|
@ -97,6 +99,7 @@ dependencies:
|
|||
http: ^1.1.0
|
||||
image: ^4.0.17
|
||||
image_editor: ^1.3.0
|
||||
image_picker: ^1.1.1
|
||||
in_app_purchase: ^3.0.7
|
||||
intl: ^0.18.0
|
||||
json_annotation: ^4.8.0
|
||||
|
@ -159,6 +162,9 @@ dependencies:
|
|||
uni_links: ^0.5.1
|
||||
url_launcher: ^6.0.3
|
||||
uuid: ^3.0.7
|
||||
video_editor:
|
||||
git:
|
||||
url: https://github.com/prateekmedia/video_editor.git
|
||||
video_player:
|
||||
git:
|
||||
url: https://github.com/ente-io/packages.git
|
||||
|
|