mirror of
https://github.com/flutter/holobooth.git
synced 2025-08-24 07:01:02 +08:00
feat: precache backgrounds for convert and share pages (#406)
Co-authored-by: Oscar <martinm.oscar@gmail.com>
This commit is contained in:
@ -9,6 +9,12 @@ import 'package:holobooth/share/share.dart';
|
||||
import 'package:holobooth_ui/holobooth_ui.dart';
|
||||
import 'package:screen_recorder/screen_recorder.dart';
|
||||
|
||||
@visibleForTesting
|
||||
typedef PrecacheImageFn = Future<void> Function(
|
||||
ImageProvider provider,
|
||||
BuildContext context,
|
||||
);
|
||||
|
||||
class ConvertPage extends StatelessWidget {
|
||||
const ConvertPage({
|
||||
required this.frames,
|
||||
@ -37,7 +43,12 @@ class ConvertPage extends StatelessWidget {
|
||||
|
||||
@visibleForTesting
|
||||
class ConvertView extends StatefulWidget {
|
||||
const ConvertView({super.key});
|
||||
const ConvertView({
|
||||
super.key,
|
||||
this.precacheImageFn = precacheImage,
|
||||
});
|
||||
|
||||
final PrecacheImageFn precacheImageFn;
|
||||
|
||||
@override
|
||||
State<ConvertView> createState() => _ConvertViewState();
|
||||
@ -49,6 +60,10 @@ class _ConvertViewState extends State<ConvertView> {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
context.read<ConvertBloc>().add(const GenerateFramesRequested());
|
||||
await widget.precacheImageFn(
|
||||
Assets.backgrounds.shareBackground.provider(),
|
||||
context,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,12 @@ import 'package:holobooth/in_experience_selection/in_experience_selection.dart';
|
||||
import 'package:holobooth/photo_booth/photo_booth.dart';
|
||||
import 'package:holobooth_ui/holobooth_ui.dart';
|
||||
|
||||
@visibleForTesting
|
||||
typedef PrecacheImageFn = Future<void> Function(
|
||||
ImageProvider provider,
|
||||
BuildContext context,
|
||||
);
|
||||
|
||||
class PhotoBoothPage extends StatelessWidget {
|
||||
const PhotoBoothPage({super.key});
|
||||
|
||||
@ -33,7 +39,12 @@ class PhotoBoothPage extends StatelessWidget {
|
||||
}
|
||||
|
||||
class PhotoBoothView extends StatefulWidget {
|
||||
const PhotoBoothView({super.key});
|
||||
const PhotoBoothView({
|
||||
super.key,
|
||||
this.precacheImageFn = precacheImage,
|
||||
});
|
||||
|
||||
final PrecacheImageFn precacheImageFn;
|
||||
|
||||
@override
|
||||
State<PhotoBoothView> createState() => _PhotoBoothViewState();
|
||||
@ -51,6 +62,12 @@ class _PhotoBoothViewState extends State<PhotoBoothView> {
|
||||
loop: true,
|
||||
child: BlocListener<PhotoBoothBloc, PhotoBoothState>(
|
||||
listener: (context, state) {
|
||||
if (state.isRecording) {
|
||||
widget.precacheImageFn(
|
||||
Assets.backgrounds.loadingBackground.provider(),
|
||||
context,
|
||||
);
|
||||
}
|
||||
if (state.isFinished) {
|
||||
_audioPlayerController.stopAudio();
|
||||
|
||||
|
@ -5,8 +5,10 @@ import 'dart:ui';
|
||||
import 'package:bloc_test/bloc_test.dart';
|
||||
import 'package:convert_repository/convert_repository.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:holobooth/assets/assets.dart';
|
||||
import 'package:holobooth/convert/convert.dart';
|
||||
import 'package:holobooth_ui/holobooth_ui.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
@ -129,6 +131,37 @@ void main() {
|
||||
|
||||
verify(() => convertBloc.add(GenerateFramesRequested())).called(1);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'precaches the share background after widget has been initialized',
|
||||
(tester) async {
|
||||
ImageProvider? cachedImage;
|
||||
Future<void> precacheImageFn(
|
||||
ImageProvider provider,
|
||||
BuildContext context,
|
||||
) async {
|
||||
cachedImage = provider;
|
||||
}
|
||||
|
||||
await tester.pumpSubject(
|
||||
ConvertView(
|
||||
precacheImageFn: precacheImageFn,
|
||||
),
|
||||
convertBloc,
|
||||
);
|
||||
|
||||
expect(
|
||||
(cachedImage! as AssetImage).keyName,
|
||||
Assets.backgrounds.shareBackground.keyName,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('uses precacheImage function by default', (tester) async {
|
||||
expect(
|
||||
ConvertView().precacheImageFn,
|
||||
precacheImage,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -213,6 +213,50 @@ void main() {
|
||||
expect(find.byType(ConvertPage), findsOneWidget);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'precaches loading background when recording starts',
|
||||
(tester) async {
|
||||
ImageProvider? cachedImage;
|
||||
Future<void> precacheImageFn(
|
||||
ImageProvider provider,
|
||||
BuildContext context,
|
||||
) async {
|
||||
cachedImage = provider;
|
||||
}
|
||||
|
||||
whenListen(
|
||||
photoBoothBloc,
|
||||
Stream.value(
|
||||
PhotoBoothState(isRecording: true),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpSubject(
|
||||
PhotoBoothView(
|
||||
precacheImageFn: precacheImageFn,
|
||||
),
|
||||
photoBoothBloc: photoBoothBloc,
|
||||
inExperienceSelectionBloc: inExperienceSelectionBloc,
|
||||
avatarDetectorBloc: avatarDetectorBloc,
|
||||
convertRepository: convertRepository,
|
||||
);
|
||||
|
||||
await tester.pump();
|
||||
|
||||
expect(
|
||||
(cachedImage! as AssetImage).keyName,
|
||||
Assets.backgrounds.loadingBackground.keyName,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('uses precacheImage function by default', (tester) async {
|
||||
expect(
|
||||
PhotoBoothView().precacheImageFn,
|
||||
precacheImage,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user