11import "package:flutter/material.dart" ;
2+ import "package:flutter_image_compress/flutter_image_compress.dart" ;
3+ import "package:logging/logging.dart" ;
4+ import "package:photo_manager/photo_manager.dart" ;
25import "package:photos/generated/l10n.dart" ;
36import 'package:photos/models/file/file.dart' ;
7+ import "package:photos/services/sync/sync_service.dart" ;
8+ import "package:photos/ui/notification/toast.dart" ;
9+ import "package:photos/ui/tools/collage/collage_app_bar.dart" ;
410import "package:photos/ui/tools/collage/collage_test_grid.dart" ;
511import "package:photos/ui/tools/collage/collage_with_five_items.dart" ;
612import "package:photos/ui/tools/collage/collage_with_four_items.dart" ;
713import "package:photos/ui/tools/collage/collage_with_six_items.dart" ;
814import "package:photos/ui/tools/collage/collage_with_three_items.dart" ;
915import "package:photos/ui/tools/collage/collage_with_two_items.dart" ;
16+ import "package:photos/ui/viewer/file/detail_page.dart" ;
17+ import "package:photos/utils/navigation_util.dart" ;
18+ import "package:widgets_to_image/widgets_to_image.dart" ;
1019
11- class CollageCreatorPage extends StatelessWidget {
20+ class CollageCreatorPage extends StatefulWidget {
1221 static const int _collageItemsMin = 2 ;
1322 static const int _collageItemsMax = 6 ;
1423 static bool isValidCount (int count) {
@@ -19,66 +28,141 @@ class CollageCreatorPage extends StatelessWidget {
1928
2029 const CollageCreatorPage (this .files, {super .key});
2130
31+ @override
32+ State <CollageCreatorPage > createState () => _CollageCreatorPageState ();
33+ }
34+
35+ class _CollageCreatorPageState extends State <CollageCreatorPage > {
36+ final _logger = Logger ("CollageCreatorPage" );
37+ WidgetsToImageController ? _controller;
38+ bool _isSaving = false ;
39+
40+ void _onControllerReady (WidgetsToImageController controller) {
41+ setState (() {
42+ _controller = controller;
43+ });
44+ }
45+
46+ Future <void > _saveCollage () async {
47+ if (_controller == null || _isSaving) return ;
48+
49+ setState (() {
50+ _isSaving = true ;
51+ });
52+
53+ try {
54+ final bytes = await _controller! .capture ();
55+ _logger.info ('Size before compression = ${bytes !.length }' );
56+ final compressedBytes = await FlutterImageCompress .compressWithList (
57+ bytes,
58+ quality: 80 ,
59+ );
60+ _logger.info ('Size after compression = ${compressedBytes .length }' );
61+ final fileName = "ente_collage_" +
62+ DateTime .now ().microsecondsSinceEpoch.toString () +
63+ ".jpeg" ;
64+ final newAsset = await (PhotoManager .editor
65+ .saveImage (
66+ compressedBytes,
67+ filename: fileName,
68+ relativePath: "ente Collages" ,
69+ )
70+ .onError ((err, st) async {
71+ return await (PhotoManager .editor.saveImage (
72+ compressedBytes,
73+ filename: fileName,
74+ ));
75+ }));
76+ final newFile = await EnteFile .fromAsset ("ente Collages" , newAsset);
77+ SyncService .instance.sync ().ignore ();
78+ showShortToast (context, AppLocalizations .of (context).collageSaved);
79+ replacePage (
80+ context,
81+ DetailPage (
82+ DetailPageConfiguration ([newFile], 0 , "collage" ),
83+ ),
84+ result: true ,
85+ );
86+ } catch (e, s) {
87+ _logger.severe (e, s);
88+ showShortToast (
89+ context,
90+ AppLocalizations .of (context).somethingWentWrong,
91+ );
92+ } finally {
93+ if (mounted) {
94+ setState (() {
95+ _isSaving = false ;
96+ });
97+ }
98+ }
99+ }
100+
22101 @override
23102 Widget build (BuildContext context) {
24103 return Scaffold (
25- appBar: AppBar (
26- elevation : 0 ,
27- title : Text ( AppLocalizations . of (context).createCollage) ,
104+ appBar: CollageAppBar (
105+ onSave : _saveCollage ,
106+ isSaveEnabled : _controller != null && ! _isSaving ,
28107 ),
29108 body: _getBody (context),
30109 );
31110 }
32111
33112 Widget _getBody (BuildContext context) {
34- final count = files.length;
113+ final count = widget. files.length;
35114 Widget collage;
36115 switch (count) {
37116 case 2 :
38117 collage = CollageWithTwoItems (
39- files[0 ],
40- files[1 ],
118+ widget.files[0 ],
119+ widget.files[1 ],
120+ onControllerReady: _onControllerReady,
41121 );
42122 break ;
43123 case 3 :
44124 collage = CollageWithThreeItems (
45- files[0 ],
46- files[1 ],
47- files[2 ],
125+ widget.files[0 ],
126+ widget.files[1 ],
127+ widget.files[2 ],
128+ onControllerReady: _onControllerReady,
48129 );
49130 break ;
50131 case 4 :
51132 collage = CollageWithFourItems (
52- files[0 ],
53- files[1 ],
54- files[2 ],
55- files[3 ],
133+ widget.files[0 ],
134+ widget.files[1 ],
135+ widget.files[2 ],
136+ widget.files[3 ],
137+ onControllerReady: _onControllerReady,
56138 );
57139 break ;
58140 case 5 :
59141 collage = CollageWithFiveItems (
60- files[0 ],
61- files[1 ],
62- files[2 ],
63- files[3 ],
64- files[4 ],
142+ widget.files[0 ],
143+ widget.files[1 ],
144+ widget.files[2 ],
145+ widget.files[3 ],
146+ widget.files[4 ],
147+ onControllerReady: _onControllerReady,
65148 );
66149 break ;
67150 case 6 :
68151 collage = CollageWithSixItems (
69- files[0 ],
70- files[1 ],
71- files[2 ],
72- files[3 ],
73- files[4 ],
74- files[5 ],
152+ widget.files[0 ],
153+ widget.files[1 ],
154+ widget.files[2 ],
155+ widget.files[3 ],
156+ widget.files[4 ],
157+ widget.files[5 ],
158+ onControllerReady: _onControllerReady,
75159 );
76160 break ;
77161 default :
78162 collage = const TestGrid ();
79163 }
80164 return Padding (
81- padding: const EdgeInsets .all ( 12 ),
165+ padding: const EdgeInsets .symmetric (horizontal : 16 , vertical : 12 ),
82166 child: collage,
83167 );
84168 }
0 commit comments