mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-05-25 00:52:12 +00:00
Fix: Issue with focus changing when taking a picture
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
This commit is contained in:
parent
2d6a2e436f
commit
f42a49cadf
6 changed files with 110 additions and 104 deletions
|
|
@ -7,6 +7,7 @@
|
|||
- Improved: The blue verification checkmark now displays the total number of verifications.
|
||||
- Fix: Issue with receiving messages when user closed app while decrypting
|
||||
- Fix: Background message fetching reliability.
|
||||
- Fix: Issue with focus changing when taking a picture
|
||||
|
||||
## 0.2.16
|
||||
|
||||
|
|
|
|||
|
|
@ -85,22 +85,31 @@ class MainCameraController {
|
|||
FaceFilterType _currentFilterType = FaceFilterType.none;
|
||||
FaceFilterType get currentFilterType => _currentFilterType;
|
||||
|
||||
Future<void>? _initializeFuture;
|
||||
Future<void>? _pendingDisposal;
|
||||
|
||||
Future<void> closeCamera() async {
|
||||
contactsVerified = {};
|
||||
scannedNewProfiles = {};
|
||||
scannedUrl = null;
|
||||
try {
|
||||
await cameraController?.stopImageStream();
|
||||
// ignore: empty_catches
|
||||
} catch (e) {}
|
||||
final cameraControllerTemp = cameraController;
|
||||
cameraController = null;
|
||||
final initFutureTemp = _initializeFuture;
|
||||
_initializeFuture = null;
|
||||
// prevents: CameraException(Disposed CameraController, buildPreview() was called on a disposed CameraController.)
|
||||
_pendingDisposal = Future.delayed(
|
||||
const Duration(milliseconds: 100),
|
||||
() async {
|
||||
try {
|
||||
if (initFutureTemp != null) {
|
||||
await initFutureTemp;
|
||||
}
|
||||
// ignore: empty_catches
|
||||
} catch (e) {}
|
||||
try {
|
||||
await cameraControllerTemp?.stopImageStream();
|
||||
// ignore: empty_catches
|
||||
} catch (e) {}
|
||||
await cameraControllerTemp?.dispose();
|
||||
},
|
||||
);
|
||||
|
|
@ -126,8 +135,7 @@ class MainCameraController {
|
|||
|
||||
if (init) {
|
||||
for (; cameraId < AppEnvironment.cameras.length; cameraId++) {
|
||||
if (AppEnvironment.cameras[cameraId].lensDirection ==
|
||||
CameraLensDirection.back) {
|
||||
if (AppEnvironment.cameras[cameraId].lensDirection == CameraLensDirection.back) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -140,12 +148,11 @@ class MainCameraController {
|
|||
AppEnvironment.cameras[cameraId],
|
||||
ResolutionPreset.high,
|
||||
enableAudio: await Permission.microphone.isGranted,
|
||||
imageFormatGroup: Platform.isAndroid
|
||||
? ImageFormatGroup.nv21
|
||||
: ImageFormatGroup.bgra8888,
|
||||
imageFormatGroup: Platform.isAndroid ? ImageFormatGroup.nv21 : ImageFormatGroup.bgra8888,
|
||||
);
|
||||
try {
|
||||
await cameraController?.initialize();
|
||||
_initializeFuture = cameraController?.initialize();
|
||||
await _initializeFuture;
|
||||
await cameraController?.startImageStream(_processCameraImage);
|
||||
await cameraController?.setZoomLevel(selectedCameraDetails.scaleFactor);
|
||||
if (userService.currentUser.videoStabilizationEnabled && !kDebugMode) {
|
||||
|
|
@ -185,14 +192,10 @@ class MainCameraController {
|
|||
await cameraController?.setFlashMode(
|
||||
selectedCameraDetails.isFlashOn ? FlashMode.always : FlashMode.off,
|
||||
);
|
||||
selectedCameraDetails.maxAvailableZoom =
|
||||
await cameraController?.getMaxZoomLevel() ?? 1;
|
||||
selectedCameraDetails.minAvailableZoom =
|
||||
await cameraController?.getMinZoomLevel() ?? 1;
|
||||
selectedCameraDetails.maxAvailableZoom = await cameraController?.getMaxZoomLevel() ?? 1;
|
||||
selectedCameraDetails.minAvailableZoom = await cameraController?.getMinZoomLevel() ?? 1;
|
||||
selectedCameraDetails
|
||||
..isZoomAble =
|
||||
selectedCameraDetails.maxAvailableZoom !=
|
||||
selectedCameraDetails.minAvailableZoom
|
||||
..isZoomAble = selectedCameraDetails.maxAvailableZoom != selectedCameraDetails.minAvailableZoom
|
||||
..cameraLoaded = true
|
||||
..cameraId = cameraId;
|
||||
|
||||
|
|
@ -214,8 +217,7 @@ class MainCameraController {
|
|||
}
|
||||
|
||||
Future<void> onTapDown(TapDownDetails details) async {
|
||||
final box =
|
||||
cameraPreviewKey.currentContext?.findRenderObject() as RenderBox?;
|
||||
final box = cameraPreviewKey.currentContext?.findRenderObject() as RenderBox?;
|
||||
if (box == null) return;
|
||||
final localPosition = box.globalToLocal(details.globalPosition);
|
||||
|
||||
|
|
@ -231,8 +233,7 @@ class MainCameraController {
|
|||
await cameraController?.setFocusPoint(Offset(dx, dy));
|
||||
await cameraController?.setFocusMode(FocusMode.auto);
|
||||
} catch (e) {
|
||||
if (e is CameraException &&
|
||||
(e.code == 'setFocusPointFailed' || e.code == 'setFocusModeFailed')) {
|
||||
if (e is CameraException && (e.code == 'setFocusPointFailed' || e.code == 'setFocusModeFailed')) {
|
||||
Log.info('Focus point or mode not supported on this device');
|
||||
} else {
|
||||
Log.warn(e);
|
||||
|
|
@ -273,8 +274,7 @@ class MainCameraController {
|
|||
if (inputImage == null) return;
|
||||
_processBarcode(inputImage);
|
||||
// check if front camera is selected
|
||||
if (cameraController?.description.lensDirection ==
|
||||
CameraLensDirection.front) {
|
||||
if (cameraController?.description.lensDirection == CameraLensDirection.front) {
|
||||
if (_currentFilterType != FaceFilterType.none) {
|
||||
_processFaces(inputImage);
|
||||
}
|
||||
|
|
@ -293,16 +293,14 @@ class MainCameraController {
|
|||
if (Platform.isIOS) {
|
||||
rotation = InputImageRotationValue.fromRawValue(sensorOrientation);
|
||||
} else if (Platform.isAndroid) {
|
||||
var rotationCompensation =
|
||||
_orientations[cameraController!.value.deviceOrientation];
|
||||
var rotationCompensation = _orientations[cameraController!.value.deviceOrientation];
|
||||
if (rotationCompensation == null) return null;
|
||||
if (camera.lensDirection == CameraLensDirection.front) {
|
||||
// front-facing
|
||||
rotationCompensation = (sensorOrientation + rotationCompensation) % 360;
|
||||
} else {
|
||||
// back-facing
|
||||
rotationCompensation =
|
||||
(sensorOrientation - rotationCompensation + 360) % 360;
|
||||
rotationCompensation = (sensorOrientation - rotationCompensation + 360) % 360;
|
||||
}
|
||||
rotation = InputImageRotationValue.fromRawValue(rotationCompensation);
|
||||
}
|
||||
|
|
@ -344,9 +342,7 @@ class MainCameraController {
|
|||
if (_isBusy) return;
|
||||
_isBusy = true;
|
||||
final barcodes = await _barcodeScanner.processImage(inputImage);
|
||||
if (inputImage.metadata?.size != null &&
|
||||
inputImage.metadata?.rotation != null &&
|
||||
cameraController != null) {
|
||||
if (inputImage.metadata?.size != null && inputImage.metadata?.rotation != null && cameraController != null) {
|
||||
final painter = BarcodeDetectorPainter(
|
||||
barcodes,
|
||||
inputImage.metadata!.size,
|
||||
|
|
@ -430,9 +426,7 @@ class MainCameraController {
|
|||
if (_isBusyFaces) return;
|
||||
_isBusyFaces = true;
|
||||
final faces = await _faceDetector.processImage(inputImage);
|
||||
if (inputImage.metadata?.size != null &&
|
||||
inputImage.metadata?.rotation != null &&
|
||||
cameraController != null) {
|
||||
if (inputImage.metadata?.size != null && inputImage.metadata?.rotation != null && cameraController != null) {
|
||||
if (faces.isNotEmpty) {
|
||||
CustomPainter? painter;
|
||||
switch (_currentFilterType) {
|
||||
|
|
|
|||
|
|
@ -31,21 +31,24 @@ class QrCodeScannerViewState extends State<QrCodeScannerView> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: GestureDetector(
|
||||
onDoubleTap: _mainCameraController.onDoubleTap,
|
||||
onTapDown: _mainCameraController.onTapDown,
|
||||
child: Stack(
|
||||
children: [
|
||||
MainCameraPreview(
|
||||
mainCameraController: _mainCameraController,
|
||||
body: Stack(
|
||||
children: [
|
||||
MainCameraPreview(
|
||||
mainCameraController: _mainCameraController,
|
||||
),
|
||||
Positioned.fill(
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onDoubleTap: _mainCameraController.onDoubleTap,
|
||||
onTapDown: _mainCameraController.onTapDown,
|
||||
),
|
||||
CameraPreviewControllerView(
|
||||
mainController: _mainCameraController,
|
||||
hideControllers: true,
|
||||
isVisible: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
CameraPreviewControllerView(
|
||||
mainController: _mainCameraController,
|
||||
hideControllers: true,
|
||||
isVisible: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,21 +33,24 @@ class CameraSendToViewState extends State<CameraSendToView> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: GestureDetector(
|
||||
onDoubleTap: _mainCameraController.onDoubleTap,
|
||||
onTapDown: _mainCameraController.onTapDown,
|
||||
child: Stack(
|
||||
children: [
|
||||
MainCameraPreview(
|
||||
mainCameraController: _mainCameraController,
|
||||
body: Stack(
|
||||
children: [
|
||||
MainCameraPreview(
|
||||
mainCameraController: _mainCameraController,
|
||||
),
|
||||
Positioned.fill(
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onDoubleTap: _mainCameraController.onDoubleTap,
|
||||
onTapDown: _mainCameraController.onTapDown,
|
||||
),
|
||||
CameraPreviewControllerView(
|
||||
mainController: _mainCameraController,
|
||||
sendToGroup: widget.sendToGroup,
|
||||
isVisible: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
CameraPreviewControllerView(
|
||||
mainController: _mainCameraController,
|
||||
sendToGroup: widget.sendToGroup,
|
||||
isVisible: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -237,53 +237,57 @@ class HomeViewState extends State<HomeView> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: GestureDetector(
|
||||
onDoubleTap: _offsetRatio == 0 ? _mainCameraController.onDoubleTap : null,
|
||||
onTapDown: _offsetRatio == 0 ? _mainCameraController.onTapDown : null,
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
MainCameraPreview(mainCameraController: _mainCameraController),
|
||||
body: Stack(
|
||||
children: <Widget>[
|
||||
MainCameraPreview(mainCameraController: _mainCameraController),
|
||||
Positioned.fill(
|
||||
child: Opacity(
|
||||
opacity: _offsetRatio,
|
||||
child: Container(
|
||||
color: context.color.surface,
|
||||
),
|
||||
),
|
||||
),
|
||||
NotificationListener<ScrollNotification>(
|
||||
onNotification: _onPageView,
|
||||
child: Positioned.fill(
|
||||
child: PageView(
|
||||
controller: _homeViewPageController,
|
||||
onPageChanged: (index) {
|
||||
setState(() {
|
||||
_activePageIdx = index;
|
||||
});
|
||||
},
|
||||
children: [
|
||||
const ChatListView(),
|
||||
Container(),
|
||||
const MemoriesView(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (_offsetRatio == 0)
|
||||
Positioned.fill(
|
||||
child: Opacity(
|
||||
opacity: _offsetRatio,
|
||||
child: Container(
|
||||
color: context.color.surface,
|
||||
),
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onDoubleTap: _mainCameraController.onDoubleTap,
|
||||
onTapDown: _mainCameraController.onTapDown,
|
||||
),
|
||||
),
|
||||
NotificationListener<ScrollNotification>(
|
||||
onNotification: _onPageView,
|
||||
child: Positioned.fill(
|
||||
child: PageView(
|
||||
controller: _homeViewPageController,
|
||||
onPageChanged: (index) {
|
||||
setState(() {
|
||||
_activePageIdx = index;
|
||||
});
|
||||
},
|
||||
children: [
|
||||
const ChatListView(),
|
||||
Container(),
|
||||
const MemoriesView(),
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: (_offsetRatio > 0.25) ? MediaQuery.sizeOf(context).height * 2 : 0,
|
||||
child: Opacity(
|
||||
opacity: 1 - (_offsetRatio * 4) % 1,
|
||||
child: CameraPreviewControllerView(
|
||||
mainController: _mainCameraController,
|
||||
isVisible: ((1 - (_offsetRatio * 4) % 1) == 1) && _activePageIdx == 1,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: (_offsetRatio > 0.25) ? MediaQuery.sizeOf(context).height * 2 : 0,
|
||||
child: Opacity(
|
||||
opacity: 1 - (_offsetRatio * 4) % 1,
|
||||
child: CameraPreviewControllerView(
|
||||
mainController: _mainCameraController,
|
||||
isVisible: ((1 - (_offsetRatio * 4) % 1) == 1) && _activePageIdx == 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: AnimatedSize(
|
||||
duration: const Duration(milliseconds: 250),
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class _PublicProfileViewState extends State<PublicProfileView> {
|
|||
SizedBox(width: 15),
|
||||
],
|
||||
),
|
||||
body: Column(
|
||||
body: ListView(
|
||||
children: [
|
||||
Container(width: double.infinity),
|
||||
const SizedBox(height: 10),
|
||||
|
|
@ -75,6 +75,7 @@ class _PublicProfileViewState extends State<PublicProfileView> {
|
|||
Text(
|
||||
userService.currentUser.username,
|
||||
style: const TextStyle(fontSize: 24),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const Divider(),
|
||||
|
|
|
|||
Loading…
Reference in a new issue