mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 09:28:41 +00:00
fix camera freeze issue
This commit is contained in:
parent
5d4fd66879
commit
aeda40d34f
5 changed files with 117 additions and 112 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -46,3 +46,4 @@ app.*.map.json
|
||||||
/android/app/release
|
/android/app/release
|
||||||
/android/app/.cxx/
|
/android/app/.cxx/
|
||||||
android/.kotlin/
|
android/.kotlin/
|
||||||
|
devtools_options.yaml
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,36 @@
|
||||||
import 'package:camera/camera.dart';
|
import 'package:camera/camera.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:screenshot/screenshot.dart';
|
import 'package:screenshot/screenshot.dart';
|
||||||
import 'package:twonly/src/views/camera/camera_send_to_view.dart';
|
|
||||||
import 'package:twonly/src/views/components/media_view_sizing.dart';
|
import 'package:twonly/src/views/components/media_view_sizing.dart';
|
||||||
import 'package:twonly/src/views/home.view.dart';
|
|
||||||
|
|
||||||
class HomeViewCameraPreview extends StatefulWidget {
|
class HomeViewCameraPreview extends StatelessWidget {
|
||||||
const HomeViewCameraPreview({
|
const HomeViewCameraPreview({
|
||||||
|
required this.controller,
|
||||||
|
required this.screenshotController,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
final CameraController? controller;
|
||||||
State<HomeViewCameraPreview> createState() => _HomeViewCameraPreviewState();
|
final ScreenshotController screenshotController;
|
||||||
}
|
|
||||||
|
|
||||||
class _HomeViewCameraPreviewState extends State<HomeViewCameraPreview> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (HomeViewState.cameraController == null ||
|
if (controller == null || !controller!.value.isInitialized) {
|
||||||
!HomeViewState.cameraController!.value.isInitialized) {
|
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
return Positioned.fill(
|
return Positioned.fill(
|
||||||
child: MediaViewSizing(
|
child: MediaViewSizing(
|
||||||
child: Screenshot(
|
child: Screenshot(
|
||||||
controller: HomeViewState.screenshotController,
|
controller: screenshotController,
|
||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 9 / 16,
|
aspectRatio: 9 / 16,
|
||||||
child: ClipRect(
|
child: ClipRect(
|
||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width:
|
width: controller!.value.previewSize!.height,
|
||||||
HomeViewState.cameraController!.value.previewSize!.height,
|
height: controller!.value.previewSize!.width,
|
||||||
height:
|
child: CameraPreview(controller!),
|
||||||
HomeViewState.cameraController!.value.previewSize!.width,
|
|
||||||
child: CameraPreview(HomeViewState.cameraController!),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -46,37 +41,34 @@ class _HomeViewCameraPreviewState extends State<HomeViewCameraPreview> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SendToCameraPreview extends StatefulWidget {
|
class SendToCameraPreview extends StatelessWidget {
|
||||||
const SendToCameraPreview({
|
const SendToCameraPreview({
|
||||||
|
required this.cameraController,
|
||||||
|
required this.screenshotController,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
final CameraController? cameraController;
|
||||||
State<SendToCameraPreview> createState() => _SendToCameraPreviewState();
|
final ScreenshotController screenshotController;
|
||||||
}
|
|
||||||
|
|
||||||
class _SendToCameraPreviewState extends State<SendToCameraPreview> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (CameraSendToViewState.cameraController == null ||
|
if (cameraController == null || !cameraController!.value.isInitialized) {
|
||||||
!CameraSendToViewState.cameraController!.value.isInitialized) {
|
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
return Positioned.fill(
|
return Positioned.fill(
|
||||||
child: MediaViewSizing(
|
child: MediaViewSizing(
|
||||||
child: Screenshot(
|
child: Screenshot(
|
||||||
controller: CameraSendToViewState.screenshotController,
|
controller: screenshotController,
|
||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 9 / 16,
|
aspectRatio: 9 / 16,
|
||||||
child: ClipRect(
|
child: ClipRect(
|
||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: CameraSendToViewState
|
width: cameraController!.value.previewSize!.height,
|
||||||
.cameraController!.value.previewSize!.height,
|
height: cameraController!.value.previewSize!.width,
|
||||||
height: CameraSendToViewState
|
child: CameraPreview(cameraController!),
|
||||||
.cameraController!.value.previewSize!.width,
|
|
||||||
child: CameraPreview(CameraSendToViewState.cameraController!),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ import 'package:twonly/src/views/camera/camera_preview_components/permissions_vi
|
||||||
import 'package:twonly/src/views/camera/camera_preview_components/send_to.dart';
|
import 'package:twonly/src/views/camera/camera_preview_components/send_to.dart';
|
||||||
import 'package:twonly/src/views/camera/camera_preview_components/video_recording_time.dart';
|
import 'package:twonly/src/views/camera/camera_preview_components/video_recording_time.dart';
|
||||||
import 'package:twonly/src/views/camera/camera_preview_components/zoom_selector.dart';
|
import 'package:twonly/src/views/camera/camera_preview_components/zoom_selector.dart';
|
||||||
import 'package:twonly/src/views/camera/camera_send_to_view.dart';
|
|
||||||
import 'package:twonly/src/views/camera/image_editor/action_button.dart';
|
import 'package:twonly/src/views/camera/image_editor/action_button.dart';
|
||||||
import 'package:twonly/src/views/camera/share_image_editor_view.dart';
|
import 'package:twonly/src/views/camera/share_image_editor_view.dart';
|
||||||
import 'package:twonly/src/views/components/media_view_sizing.dart';
|
import 'package:twonly/src/views/components/media_view_sizing.dart';
|
||||||
|
|
@ -83,23 +82,21 @@ class SelectedCameraDetails {
|
||||||
bool cameraLoaded = false;
|
bool cameraLoaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CameraPreviewControllerView extends StatefulWidget {
|
class CameraPreviewControllerView extends StatelessWidget {
|
||||||
const CameraPreviewControllerView({
|
const CameraPreviewControllerView({
|
||||||
|
required this.cameraController,
|
||||||
required this.selectCamera,
|
required this.selectCamera,
|
||||||
required this.isHomeView,
|
required this.selectedCameraDetails,
|
||||||
|
required this.screenshotController,
|
||||||
super.key,
|
super.key,
|
||||||
this.sendTo,
|
this.sendTo,
|
||||||
});
|
});
|
||||||
final Contact? sendTo;
|
final Contact? sendTo;
|
||||||
final void Function(int sCameraId, bool init, bool enableAudio) selectCamera;
|
final void Function(int sCameraId, bool init, bool enableAudio) selectCamera;
|
||||||
final bool isHomeView;
|
final CameraController? cameraController;
|
||||||
|
final SelectedCameraDetails selectedCameraDetails;
|
||||||
|
final ScreenshotController screenshotController;
|
||||||
|
|
||||||
@override
|
|
||||||
State<CameraPreviewControllerView> createState() =>
|
|
||||||
_CameraPreviewControllerView();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _CameraPreviewControllerView extends State<CameraPreviewControllerView> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
|
|
@ -108,13 +105,16 @@ class _CameraPreviewControllerView extends State<CameraPreviewControllerView> {
|
||||||
if (snap.hasData) {
|
if (snap.hasData) {
|
||||||
if (snap.data!) {
|
if (snap.data!) {
|
||||||
return CameraPreviewView(
|
return CameraPreviewView(
|
||||||
sendTo: widget.sendTo,
|
sendTo: sendTo,
|
||||||
selectCamera: widget.selectCamera,
|
selectCamera: selectCamera,
|
||||||
isHomeView: widget.isHomeView,
|
cameraController: cameraController,
|
||||||
|
selectedCameraDetails: selectedCameraDetails,
|
||||||
|
screenshotController: screenshotController,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return PermissionHandlerView(onSuccess: () {
|
return PermissionHandlerView(onSuccess: () {
|
||||||
setState(() {});
|
// setState(() {});
|
||||||
|
selectCamera(0, true, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -126,14 +126,19 @@ class _CameraPreviewControllerView extends State<CameraPreviewControllerView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
class CameraPreviewView extends StatefulWidget {
|
class CameraPreviewView extends StatefulWidget {
|
||||||
const CameraPreviewView(
|
const CameraPreviewView({
|
||||||
{required this.selectCamera,
|
required this.selectCamera,
|
||||||
required this.isHomeView,
|
required this.cameraController,
|
||||||
super.key,
|
required this.selectedCameraDetails,
|
||||||
this.sendTo});
|
required this.screenshotController,
|
||||||
|
super.key,
|
||||||
|
this.sendTo,
|
||||||
|
});
|
||||||
final Contact? sendTo;
|
final Contact? sendTo;
|
||||||
final bool isHomeView;
|
|
||||||
final void Function(int sCameraId, bool init, bool enableAudio) selectCamera;
|
final void Function(int sCameraId, bool init, bool enableAudio) selectCamera;
|
||||||
|
final CameraController? cameraController;
|
||||||
|
final SelectedCameraDetails selectedCameraDetails;
|
||||||
|
final ScreenshotController screenshotController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<CameraPreviewView> createState() => _CameraPreviewViewState();
|
State<CameraPreviewView> createState() => _CameraPreviewViewState();
|
||||||
|
|
@ -163,18 +168,6 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
initAsync();
|
initAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
CameraController? get cameraController => widget.isHomeView
|
|
||||||
? HomeViewState.cameraController
|
|
||||||
: CameraSendToViewState.cameraController;
|
|
||||||
|
|
||||||
SelectedCameraDetails get selectedCameraDetails => widget.isHomeView
|
|
||||||
? HomeViewState.selectedCameraDetails
|
|
||||||
: CameraSendToViewState.selectedCameraDetails;
|
|
||||||
|
|
||||||
ScreenshotController get screenshotController => widget.isHomeView
|
|
||||||
? HomeViewState.screenshotController
|
|
||||||
: CameraSendToViewState.screenshotController;
|
|
||||||
|
|
||||||
Future<void> initAsync() async {
|
Future<void> initAsync() async {
|
||||||
hasAudioPermission = await Permission.microphone.isGranted;
|
hasAudioPermission = await Permission.microphone.isGranted;
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
@ -200,15 +193,15 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateScaleFactor(double newScale) async {
|
Future<void> updateScaleFactor(double newScale) async {
|
||||||
if (selectedCameraDetails.scaleFactor == newScale ||
|
if (widget.selectedCameraDetails.scaleFactor == newScale ||
|
||||||
cameraController == null) {
|
widget.cameraController == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await cameraController?.setZoomLevel(newScale.clamp(
|
await widget.cameraController?.setZoomLevel(newScale.clamp(
|
||||||
selectedCameraDetails.minAvailableZoom,
|
widget.selectedCameraDetails.minAvailableZoom,
|
||||||
selectedCameraDetails.maxAvailableZoom));
|
widget.selectedCameraDetails.maxAvailableZoom));
|
||||||
setState(() {
|
setState(() {
|
||||||
selectedCameraDetails.scaleFactor = newScale;
|
widget.selectedCameraDetails.scaleFactor = newScale;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,26 +233,28 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
setState(() {
|
setState(() {
|
||||||
sharePreviewIsShown = true;
|
sharePreviewIsShown = true;
|
||||||
});
|
});
|
||||||
if (selectedCameraDetails.isFlashOn) {
|
if (widget.selectedCameraDetails.isFlashOn) {
|
||||||
if (isFront) {
|
if (isFront) {
|
||||||
setState(() {
|
setState(() {
|
||||||
showSelfieFlash = true;
|
showSelfieFlash = true;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await cameraController?.setFlashMode(FlashMode.torch);
|
await widget.cameraController?.setFlashMode(FlashMode.torch);
|
||||||
}
|
}
|
||||||
await Future.delayed(const Duration(milliseconds: 1000));
|
await Future.delayed(const Duration(milliseconds: 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
await cameraController?.pausePreview();
|
await widget.cameraController?.pausePreview();
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
||||||
await cameraController?.setFlashMode(
|
await widget.cameraController?.setFlashMode(
|
||||||
selectedCameraDetails.isFlashOn ? FlashMode.always : FlashMode.off);
|
widget.selectedCameraDetails.isFlashOn
|
||||||
|
? FlashMode.always
|
||||||
|
: FlashMode.off);
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
||||||
imageBytes = screenshotController.capture(
|
imageBytes = widget.screenshotController
|
||||||
pixelRatio: MediaQuery.of(context).devicePixelRatio);
|
.capture(pixelRatio: MediaQuery.of(context).devicePixelRatio);
|
||||||
|
|
||||||
if (await pushMediaEditor(imageBytes, null)) {
|
if (await pushMediaEditor(imageBytes, null)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -305,26 +300,30 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
widget.selectCamera(selectedCameraDetails.cameraId, false, false);
|
widget.selectCamera(widget.selectedCameraDetails.cameraId, false, false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get isFront =>
|
bool get isFront =>
|
||||||
cameraController?.description.lensDirection == CameraLensDirection.front;
|
widget.cameraController?.description.lensDirection ==
|
||||||
|
CameraLensDirection.front;
|
||||||
|
|
||||||
Future<void> onPanUpdate(dynamic details) async {
|
Future<void> onPanUpdate(dynamic details) async {
|
||||||
if (isFront || details == null) {
|
if (isFront || details == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cameraController == null) return;
|
if (widget.cameraController == null ||
|
||||||
if (!cameraController!.value.isInitialized) return;
|
!widget.cameraController!.value.isInitialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
selectedCameraDetails.scaleFactor =
|
widget.selectedCameraDetails.scaleFactor =
|
||||||
// ignore: avoid_dynamic_calls
|
// ignore: avoid_dynamic_calls
|
||||||
(baseScaleFactor + (basePanY - (details.localPosition.dy as int)) / 30)
|
(baseScaleFactor + (basePanY - (details.localPosition.dy as int)) / 30)
|
||||||
.clamp(1, selectedCameraDetails.maxAvailableZoom);
|
.clamp(1, widget.selectedCameraDetails.maxAvailableZoom);
|
||||||
|
|
||||||
await cameraController!.setZoomLevel(selectedCameraDetails.scaleFactor);
|
await widget.cameraController!
|
||||||
|
.setZoomLevel(widget.selectedCameraDetails.scaleFactor);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
@ -353,12 +352,13 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> startVideoRecording() async {
|
Future<void> startVideoRecording() async {
|
||||||
if (cameraController != null && cameraController!.value.isRecordingVideo) {
|
if (widget.cameraController != null &&
|
||||||
|
widget.cameraController!.value.isRecordingVideo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (hasAudioPermission && videoWithAudio) {
|
if (hasAudioPermission && videoWithAudio) {
|
||||||
widget.selectCamera(
|
widget.selectCamera(
|
||||||
selectedCameraDetails.cameraId,
|
widget.selectedCameraDetails.cameraId,
|
||||||
false,
|
false,
|
||||||
await Permission.microphone.isGranted && videoWithAudio,
|
await Permission.microphone.isGranted && videoWithAudio,
|
||||||
);
|
);
|
||||||
|
|
@ -369,7 +369,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await cameraController?.startVideoRecording();
|
await widget.cameraController?.startVideoRecording();
|
||||||
videoRecordingTimer =
|
videoRecordingTimer =
|
||||||
Timer.periodic(const Duration(milliseconds: 15), (timer) {
|
Timer.periodic(const Duration(milliseconds: 15), (timer) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
@ -401,7 +401,8 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
videoRecordingTimer?.cancel();
|
videoRecordingTimer?.cancel();
|
||||||
videoRecordingTimer = null;
|
videoRecordingTimer = null;
|
||||||
}
|
}
|
||||||
if (cameraController == null || !cameraController!.value.isRecordingVideo) {
|
if (widget.cameraController == null ||
|
||||||
|
!widget.cameraController!.value.isRecordingVideo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -412,7 +413,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
sharePreviewIsShown = true;
|
sharePreviewIsShown = true;
|
||||||
});
|
});
|
||||||
File? videoPathFile;
|
File? videoPathFile;
|
||||||
final videoPath = await cameraController?.stopVideoRecording();
|
final videoPath = await widget.cameraController?.stopVideoRecording();
|
||||||
if (videoPath != null) {
|
if (videoPath != null) {
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
// see https://github.com/flutter/flutter/issues/148335
|
// see https://github.com/flutter/flutter/issues/148335
|
||||||
|
|
@ -422,7 +423,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
videoPathFile = File(videoPath.path);
|
videoPathFile = File(videoPath.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await cameraController?.pausePreview();
|
await widget.cameraController?.pausePreview();
|
||||||
if (await pushMediaEditor(null, videoPathFile)) {
|
if (await pushMediaEditor(null, videoPathFile)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -450,8 +451,8 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (selectedCameraDetails.cameraId >= gCameras.length ||
|
if (widget.selectedCameraDetails.cameraId >= gCameras.length ||
|
||||||
cameraController == null) {
|
widget.cameraController == null) {
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
return MediaViewSizing(
|
return MediaViewSizing(
|
||||||
|
|
@ -462,14 +463,14 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
}
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
basePanY = details.localPosition.dy;
|
basePanY = details.localPosition.dy;
|
||||||
baseScaleFactor = selectedCameraDetails.scaleFactor;
|
baseScaleFactor = widget.selectedCameraDetails.scaleFactor;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onLongPressMoveUpdate: onPanUpdate,
|
onLongPressMoveUpdate: onPanUpdate,
|
||||||
onLongPressStart: (details) {
|
onLongPressStart: (details) {
|
||||||
setState(() {
|
setState(() {
|
||||||
basePanY = details.localPosition.dy;
|
basePanY = details.localPosition.dy;
|
||||||
baseScaleFactor = selectedCameraDetails.scaleFactor;
|
baseScaleFactor = widget.selectedCameraDetails.scaleFactor;
|
||||||
});
|
});
|
||||||
// Get the position of the pointer
|
// Get the position of the pointer
|
||||||
final renderBox =
|
final renderBox =
|
||||||
|
|
@ -523,28 +524,28 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
tooltipText: context.lang.switchFrontAndBackCamera,
|
tooltipText: context.lang.switchFrontAndBackCamera,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
widget.selectCamera(
|
widget.selectCamera(
|
||||||
(selectedCameraDetails.cameraId + 1) % 2,
|
(widget.selectedCameraDetails.cameraId + 1) % 2,
|
||||||
false,
|
false,
|
||||||
false);
|
false);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ActionButton(
|
ActionButton(
|
||||||
selectedCameraDetails.isFlashOn
|
widget.selectedCameraDetails.isFlashOn
|
||||||
? Icons.flash_on_rounded
|
? Icons.flash_on_rounded
|
||||||
: Icons.flash_off_rounded,
|
: Icons.flash_off_rounded,
|
||||||
tooltipText: context.lang.toggleFlashLight,
|
tooltipText: context.lang.toggleFlashLight,
|
||||||
color: selectedCameraDetails.isFlashOn
|
color: widget.selectedCameraDetails.isFlashOn
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: Colors.white.withAlpha(160),
|
: Colors.white.withAlpha(160),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (selectedCameraDetails.isFlashOn) {
|
if (widget.selectedCameraDetails.isFlashOn) {
|
||||||
await cameraController
|
await widget.cameraController
|
||||||
?.setFlashMode(FlashMode.off);
|
?.setFlashMode(FlashMode.off);
|
||||||
selectedCameraDetails.isFlashOn = false;
|
widget.selectedCameraDetails.isFlashOn = false;
|
||||||
} else {
|
} else {
|
||||||
await cameraController
|
await widget.cameraController
|
||||||
?.setFlashMode(FlashMode.always);
|
?.setFlashMode(FlashMode.always);
|
||||||
selectedCameraDetails.isFlashOn = true;
|
widget.selectedCameraDetails.isFlashOn = true;
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
|
|
@ -602,17 +603,18 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
if (cameraController!.value.isInitialized &&
|
if (widget.cameraController!.value.isInitialized &&
|
||||||
selectedCameraDetails.isZoomAble &&
|
widget.selectedCameraDetails.isZoomAble &&
|
||||||
!isFront &&
|
!isFront &&
|
||||||
!isVideoRecording)
|
!isVideoRecording)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 120,
|
width: 120,
|
||||||
child: CameraZoomButtons(
|
child: CameraZoomButtons(
|
||||||
key: widget.key,
|
key: widget.key,
|
||||||
scaleFactor: selectedCameraDetails.scaleFactor,
|
scaleFactor:
|
||||||
|
widget.selectedCameraDetails.scaleFactor,
|
||||||
updateScaleFactor: updateScaleFactor,
|
updateScaleFactor: updateScaleFactor,
|
||||||
controller: cameraController!,
|
controller: widget.cameraController!,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 30),
|
const SizedBox(height: 30),
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ class CameraSendToView extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class CameraSendToViewState extends State<CameraSendToView> {
|
class CameraSendToViewState extends State<CameraSendToView> {
|
||||||
static CameraController? cameraController;
|
CameraController? cameraController;
|
||||||
static ScreenshotController screenshotController = ScreenshotController();
|
ScreenshotController screenshotController = ScreenshotController();
|
||||||
static SelectedCameraDetails selectedCameraDetails = SelectedCameraDetails();
|
SelectedCameraDetails selectedCameraDetails = SelectedCameraDetails();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -54,11 +54,16 @@ class CameraSendToViewState extends State<CameraSendToView> {
|
||||||
onDoubleTap: toggleSelectedCamera,
|
onDoubleTap: toggleSelectedCamera,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
const SendToCameraPreview(),
|
SendToCameraPreview(
|
||||||
|
cameraController: cameraController,
|
||||||
|
screenshotController: screenshotController,
|
||||||
|
),
|
||||||
CameraPreviewControllerView(
|
CameraPreviewControllerView(
|
||||||
selectCamera: selectCamera,
|
selectCamera: selectCamera,
|
||||||
sendTo: widget.sendTo,
|
sendTo: widget.sendTo,
|
||||||
isHomeView: false,
|
cameraController: cameraController,
|
||||||
|
selectedCameraDetails: selectedCameraDetails,
|
||||||
|
screenshotController: screenshotController,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -55,9 +55,9 @@ class HomeViewState extends State<HomeView> {
|
||||||
Timer? disableCameraTimer;
|
Timer? disableCameraTimer;
|
||||||
bool initCameraStarted = true;
|
bool initCameraStarted = true;
|
||||||
|
|
||||||
static CameraController? cameraController;
|
CameraController? cameraController;
|
||||||
static ScreenshotController screenshotController = ScreenshotController();
|
ScreenshotController screenshotController = ScreenshotController();
|
||||||
static SelectedCameraDetails selectedCameraDetails = SelectedCameraDetails();
|
SelectedCameraDetails selectedCameraDetails = SelectedCameraDetails();
|
||||||
|
|
||||||
bool onPageView(ScrollNotification notification) {
|
bool onPageView(ScrollNotification notification) {
|
||||||
disableCameraTimer?.cancel();
|
disableCameraTimer?.cancel();
|
||||||
|
|
@ -145,7 +145,10 @@ class HomeViewState extends State<HomeView> {
|
||||||
onDoubleTap: offsetRatio == 0 ? toggleSelectedCamera : null,
|
onDoubleTap: offsetRatio == 0 ? toggleSelectedCamera : null,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
const HomeViewCameraPreview(),
|
HomeViewCameraPreview(
|
||||||
|
controller: cameraController,
|
||||||
|
screenshotController: screenshotController,
|
||||||
|
),
|
||||||
Shade(
|
Shade(
|
||||||
opacity: offsetRatio,
|
opacity: offsetRatio,
|
||||||
),
|
),
|
||||||
|
|
@ -177,8 +180,10 @@ class HomeViewState extends State<HomeView> {
|
||||||
child: Opacity(
|
child: Opacity(
|
||||||
opacity: 1 - (offsetRatio * 4) % 1,
|
opacity: 1 - (offsetRatio * 4) % 1,
|
||||||
child: CameraPreviewControllerView(
|
child: CameraPreviewControllerView(
|
||||||
|
cameraController: cameraController,
|
||||||
|
screenshotController: screenshotController,
|
||||||
|
selectedCameraDetails: selectedCameraDetails,
|
||||||
selectCamera: selectCamera,
|
selectCamera: selectCamera,
|
||||||
isHomeView: true,
|
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue