Skip to content

Commit a74c529

Browse files
authored
🚑️ Fix LocallyAvailableBuilder with more edge conditions (#263)
1 parent f2f7699 commit a74c529

File tree

3 files changed

+72
-53
lines changed

3 files changed

+72
-53
lines changed

lib/src/widget/builder/image_page_builder.dart

Lines changed: 52 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class _ImagePageBuilderState extends State<ImagePageBuilder> {
3535
bool _isLocallyAvailable = false;
3636
VideoPlayerController? _controller;
3737

38+
bool get _isOriginal => widget.previewThumbnailSize == null;
39+
3840
bool get _isLivePhoto => widget.asset.isLivePhoto;
3941

4042
@override
@@ -44,12 +46,17 @@ class _ImagePageBuilderState extends State<ImagePageBuilder> {
4446
}
4547

4648
Future<void> _initializeLivePhoto() async {
47-
final String? url = await widget.asset.getMediaUrl();
48-
if (!mounted || url == null) {
49+
final File? file;
50+
if (_isOriginal) {
51+
file = await widget.asset.originFileWithSubtype;
52+
} else {
53+
file = await widget.asset.fileWithSubtype;
54+
}
55+
if (!mounted || file == null) {
4956
return;
5057
}
51-
final VideoPlayerController c = VideoPlayerController.network(
52-
url,
58+
final VideoPlayerController c = VideoPlayerController.file(
59+
file,
5360
videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true),
5461
);
5562
setState(() => _controller = c);
@@ -80,7 +87,7 @@ class _ImagePageBuilderState extends State<ImagePageBuilder> {
8087
return ExtendedImage(
8188
image: AssetEntityImageProvider(
8289
asset,
83-
isOriginal: widget.previewThumbnailSize == null,
90+
isOriginal: _isOriginal,
8491
thumbnailSize: widget.previewThumbnailSize,
8592
),
8693
fit: BoxFit.contain,
@@ -107,11 +114,49 @@ class _ImagePageBuilderState extends State<ImagePageBuilder> {
107114
);
108115
}
109116

117+
Widget _buildLivePhotosWrapper(BuildContext context, AssetEntity asset) {
118+
return Stack(
119+
children: <Widget>[
120+
if (_controller?.value.isInitialized == true)
121+
Center(
122+
child: AspectRatio(
123+
aspectRatio: _controller!.value.aspectRatio,
124+
child: ValueListenableBuilder<VideoPlayerValue>(
125+
valueListenable: _controller!,
126+
builder: (_, VideoPlayerValue value, Widget? child) {
127+
return Opacity(
128+
opacity: value.isPlaying ? 1 : 0,
129+
child: child,
130+
);
131+
},
132+
child: VideoPlayer(_controller!),
133+
),
134+
),
135+
),
136+
if (_controller == null)
137+
Positioned.fill(child: _imageBuilder(context, asset))
138+
else
139+
Positioned.fill(
140+
child: ValueListenableBuilder<VideoPlayerValue>(
141+
valueListenable: _controller!,
142+
builder: (_, VideoPlayerValue value, Widget? child) {
143+
return Opacity(
144+
opacity: value.isPlaying ? 0 : 1,
145+
child: child,
146+
);
147+
},
148+
child: _imageBuilder(context, asset),
149+
),
150+
),
151+
],
152+
);
153+
}
154+
110155
@override
111156
Widget build(BuildContext context) {
112157
return LocallyAvailableBuilder(
113158
asset: widget.asset,
114-
isOriginal: widget.previewThumbnailSize == null,
159+
isOriginal: _isOriginal,
115160
builder: (BuildContext context, AssetEntity asset) {
116161
// Initialize the video controller when the asset is a Live photo
117162
// and available for further use.
@@ -130,43 +175,7 @@ class _ImagePageBuilderState extends State<ImagePageBuilder> {
130175
if (!_isLivePhoto) {
131176
return _imageBuilder(context, asset);
132177
}
133-
return Stack(
134-
children: <Widget>[
135-
if (_controller == null)
136-
_imageBuilder(context, asset)
137-
else ...<Widget>[
138-
if (_controller!.value.isInitialized)
139-
Center(
140-
child: AspectRatio(
141-
aspectRatio: _controller!.value.aspectRatio,
142-
child: ValueListenableBuilder<VideoPlayerValue>(
143-
valueListenable: _controller!,
144-
builder:
145-
(_, VideoPlayerValue value, Widget? child) {
146-
return Opacity(
147-
opacity: value.isPlaying ? 1 : 0,
148-
child: child,
149-
);
150-
},
151-
child: VideoPlayer(_controller!),
152-
),
153-
),
154-
),
155-
Positioned.fill(
156-
child: ValueListenableBuilder<VideoPlayerValue>(
157-
valueListenable: _controller!,
158-
builder: (_, VideoPlayerValue value, Widget? child) {
159-
return Opacity(
160-
opacity: value.isPlaying ? 0 : 1,
161-
child: child,
162-
);
163-
},
164-
child: _imageBuilder(context, asset),
165-
),
166-
),
167-
],
168-
],
169-
);
178+
return _buildLivePhotosWrapper(context, asset);
170179
},
171180
),
172181
);

lib/src/widget/builder/locally_available_builder.dart

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:flutter/material.dart';
88
import 'package:photo_manager/photo_manager.dart';
99

1010
import '../../constants/extensions.dart';
11+
import '../../internal/methods.dart';
1112
import '../scale_text.dart';
1213

1314
class LocallyAvailableBuilder extends StatefulWidget {
@@ -30,7 +31,6 @@ class LocallyAvailableBuilder extends StatefulWidget {
3031
class _LocallyAvailableBuilderState extends State<LocallyAvailableBuilder> {
3132
bool _isLocallyAvailable = false;
3233
PMProgressHandler? _progressHandler;
33-
File? file;
3434

3535
@override
3636
void initState() {
@@ -39,24 +39,34 @@ class _LocallyAvailableBuilderState extends State<LocallyAvailableBuilder> {
3939
}
4040

4141
Future<void> _checkLocallyAvailable() async {
42-
_isLocallyAvailable = await widget.asset.isLocallyAvailable;
42+
_isLocallyAvailable = await widget.asset.isLocallyAvailable(
43+
isOrigin: widget.isOriginal,
44+
);
4345
if (!mounted) {
4446
return;
4547
}
4648
setState(() {});
4749
if (!_isLocallyAvailable) {
4850
_progressHandler = PMProgressHandler();
49-
widget.asset
50-
.loadFile(
51-
progressHandler: _progressHandler,
52-
isOrigin: widget.isOriginal,
53-
)
54-
.then((File? f) => file = f);
51+
Future<void>(() async {
52+
final File? file = await widget.asset.loadFile(
53+
isOrigin: widget.isOriginal,
54+
withSubtype: true,
55+
progressHandler: _progressHandler,
56+
);
57+
realDebugPrint('Produced file: $file.');
58+
if (file != null) {
59+
_isLocallyAvailable = true;
60+
if (mounted) {
61+
setState(() {});
62+
}
63+
}
64+
});
5565
}
5666
_progressHandler?.stream.listen((PMProgressState s) {
67+
realDebugPrint('Handling progress: $s.');
5768
if (s.state == PMRequestState.success) {
5869
_isLocallyAvailable = true;
59-
file = null;
6070
if (mounted) {
6171
setState(() {});
6272
}

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ dependencies:
1313

1414
extended_image: ^6.0.1
1515
meta: ^1.7.0
16-
photo_manager: ^2.0.0-dev.11
16+
photo_manager: ^2.0.0-dev.14
1717
provider: ^6.0.1
1818
video_player: ^2.2.14

0 commit comments

Comments
 (0)