feat: support iOS LivePhoto backup (#950)

This commit is contained in:
Alex 2022-11-18 23:12:54 -06:00 committed by GitHub
parent 83e2cabbcc
commit 8bc64be77b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 678 additions and 243 deletions

View file

@ -15,15 +15,26 @@ import 'package:video_player/video_player.dart';
// ignore: must_be_immutable
class VideoViewerPage extends HookConsumerWidget {
final Asset asset;
final bool isMotionVideo;
final VoidCallback onVideoEnded;
const VideoViewerPage({Key? key, required this.asset}) : super(key: key);
const VideoViewerPage({
Key? key,
required this.asset,
required this.isMotionVideo,
required this.onVideoEnded,
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
if (asset.isLocal) {
final AsyncValue<File> videoFile = ref.watch(_fileFamily(asset.local!));
return videoFile.when(
data: (data) => VideoThumbnailPlayer(file: data),
data: (data) => VideoThumbnailPlayer(
file: data,
isMotionVideo: false,
onVideoEnded: () {},
),
error: (error, stackTrace) => Icon(
Icons.image_not_supported_outlined,
color: Theme.of(context).primaryColor,
@ -41,14 +52,17 @@ class VideoViewerPage extends HookConsumerWidget {
ref.watch(imageViewerStateProvider).downloadAssetStatus;
final box = Hive.box(userInfoBox);
final String jwtToken = box.get(accessTokenKey);
final String videoUrl =
'${box.get(serverEndpointKey)}/asset/file/${asset.id}';
final String videoUrl = isMotionVideo
? '${box.get(serverEndpointKey)}/asset/file/${asset.remote?.livePhotoVideoId!}'
: '${box.get(serverEndpointKey)}/asset/file/${asset.id}';
return Stack(
children: [
VideoThumbnailPlayer(
url: videoUrl,
jwtToken: jwtToken,
isMotionVideo: isMotionVideo,
onVideoEnded: onVideoEnded,
),
if (downloadAssetStatus == DownloadAssetStatus.loading)
const Center(
@ -72,9 +86,17 @@ class VideoThumbnailPlayer extends StatefulWidget {
final String? url;
final String? jwtToken;
final File? file;
final bool isMotionVideo;
final VoidCallback onVideoEnded;
const VideoThumbnailPlayer({Key? key, this.url, this.jwtToken, this.file})
: super(key: key);
const VideoThumbnailPlayer({
Key? key,
this.url,
this.jwtToken,
this.file,
required this.onVideoEnded,
required this.isMotionVideo,
}) : super(key: key);
@override
State<VideoThumbnailPlayer> createState() => _VideoThumbnailPlayerState();
@ -88,6 +110,13 @@ class _VideoThumbnailPlayerState extends State<VideoThumbnailPlayer> {
void initState() {
super.initState();
initializePlayer();
videoPlayerController.addListener(() {
if (videoPlayerController.value.position ==
videoPlayerController.value.duration) {
widget.onVideoEnded();
}
});
}
Future<void> initializePlayer() async {
@ -115,7 +144,7 @@ class _VideoThumbnailPlayerState extends State<VideoThumbnailPlayer> {
autoPlay: true,
autoInitialize: true,
allowFullScreen: true,
showControls: true,
showControls: !widget.isMotionVideo,
hideControlsTimer: const Duration(seconds: 5),
);
}