mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 15:08:41 +00:00
implement new send to version
This commit is contained in:
parent
8e1c6a8fab
commit
d488e4db2c
4 changed files with 219 additions and 115 deletions
|
|
@ -2,19 +2,20 @@ import 'dart:io';
|
||||||
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';
|
import 'package:twonly/src/views/home_view.dart';
|
||||||
|
|
||||||
class CameraPreviewWidget extends StatefulWidget {
|
class HomeViewCameraPreview extends StatefulWidget {
|
||||||
const CameraPreviewWidget({
|
const HomeViewCameraPreview({
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<CameraPreviewWidget> createState() => _CameraPreviewWidgetState();
|
State<HomeViewCameraPreview> createState() => _HomeViewCameraPreviewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CameraPreviewWidgetState extends State<CameraPreviewWidget> {
|
class _HomeViewCameraPreviewState extends State<HomeViewCameraPreview> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (HomeViewState.cameraController == null ||
|
if (HomeViewState.cameraController == null ||
|
||||||
|
|
@ -52,3 +53,53 @@ class _CameraPreviewWidgetState extends State<CameraPreviewWidget> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SendToCameraPreview extends StatefulWidget {
|
||||||
|
const SendToCameraPreview({
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SendToCameraPreview> createState() => _SendToCameraPreviewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SendToCameraPreviewState extends State<SendToCameraPreview> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (CameraSendToViewState.cameraController == null ||
|
||||||
|
!CameraSendToViewState.cameraController!.value.isInitialized) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
bool isFront =
|
||||||
|
CameraSendToViewState.cameraController?.description.lensDirection ==
|
||||||
|
CameraLensDirection.front;
|
||||||
|
return Positioned.fill(
|
||||||
|
child: MediaViewSizing(
|
||||||
|
child: Screenshot(
|
||||||
|
controller: CameraSendToViewState.screenshotController,
|
||||||
|
child: AspectRatio(
|
||||||
|
aspectRatio: 9 / 16,
|
||||||
|
child: ClipRect(
|
||||||
|
child: FittedBox(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
child: SizedBox(
|
||||||
|
width: CameraSendToViewState
|
||||||
|
.cameraController!.value.previewSize!.height,
|
||||||
|
height: CameraSendToViewState
|
||||||
|
.cameraController!.value.previewSize!.width,
|
||||||
|
child: Transform(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
transform: Matrix4.rotationY(
|
||||||
|
(isFront && Platform.isAndroid) ? 3.14 : 0),
|
||||||
|
child:
|
||||||
|
CameraPreview(CameraSendToViewState.cameraController!),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,14 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
import 'package:screenshot/screenshot.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
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/zoom_selector.dart';
|
import 'package:twonly/src/views/camera/camera_preview_components/zoom_selector.dart';
|
||||||
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.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/components/media_view_sizing.dart';
|
import 'package:twonly/src/views/components/media_view_sizing.dart';
|
||||||
import 'package:twonly/src/views/camera/camera_preview_components/permissions_view.dart';
|
import 'package:twonly/src/views/camera/camera_preview_components/permissions_view.dart';
|
||||||
|
|
@ -22,6 +24,51 @@ import 'package:twonly/src/views/home_view.dart';
|
||||||
|
|
||||||
int maxVideoRecordingTime = 15;
|
int maxVideoRecordingTime = 15;
|
||||||
|
|
||||||
|
Future<(SelectedCameraDetails, CameraController)?> initializeCameraController(
|
||||||
|
SelectedCameraDetails details,
|
||||||
|
int sCameraId,
|
||||||
|
bool init,
|
||||||
|
bool enableAudio) async {
|
||||||
|
if (sCameraId >= gCameras.length) return null;
|
||||||
|
if (init) {
|
||||||
|
for (; sCameraId < gCameras.length; sCameraId++) {
|
||||||
|
if (gCameras[sCameraId].lensDirection == CameraLensDirection.back) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
details.isZoomAble = false;
|
||||||
|
if (details.cameraId != sCameraId) {
|
||||||
|
// switch between front and back
|
||||||
|
details.scaleFactor = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraController cameraController = CameraController(
|
||||||
|
gCameras[sCameraId],
|
||||||
|
ResolutionPreset.high,
|
||||||
|
enableAudio: enableAudio,
|
||||||
|
);
|
||||||
|
|
||||||
|
await cameraController.initialize().then((_) async {
|
||||||
|
await cameraController.setZoomLevel(details.scaleFactor);
|
||||||
|
await cameraController.lockCaptureOrientation(DeviceOrientation.portraitUp);
|
||||||
|
cameraController
|
||||||
|
.setFlashMode(details.isFlashOn ? FlashMode.always : FlashMode.off);
|
||||||
|
await cameraController
|
||||||
|
.getMaxZoomLevel()
|
||||||
|
.then((double value) => details.maxAvailableZoom = value);
|
||||||
|
await cameraController
|
||||||
|
.getMinZoomLevel()
|
||||||
|
.then((double value) => details.minAvailableZoom = value);
|
||||||
|
details.isZoomAble = details.maxAvailableZoom != details.minAvailableZoom;
|
||||||
|
details.cameraLoaded = true;
|
||||||
|
details.cameraId = sCameraId;
|
||||||
|
}).catchError((Object e) {
|
||||||
|
Logger("camera_preview.dart").shout("$e");
|
||||||
|
});
|
||||||
|
return (details, cameraController);
|
||||||
|
}
|
||||||
|
|
||||||
class SelectedCameraDetails {
|
class SelectedCameraDetails {
|
||||||
double maxAvailableZoom = 1;
|
double maxAvailableZoom = 1;
|
||||||
double minAvailableZoom = 1;
|
double minAvailableZoom = 1;
|
||||||
|
|
@ -36,10 +83,12 @@ class CameraPreviewControllerView extends StatefulWidget {
|
||||||
const CameraPreviewControllerView({
|
const CameraPreviewControllerView({
|
||||||
super.key,
|
super.key,
|
||||||
required this.selectCamera,
|
required this.selectCamera,
|
||||||
|
required this.isHomeView,
|
||||||
this.sendTo,
|
this.sendTo,
|
||||||
});
|
});
|
||||||
final Contact? sendTo;
|
final Contact? sendTo;
|
||||||
final Function(int sCameraId, bool init, bool enableAudio) selectCamera;
|
final Function(int sCameraId, bool init, bool enableAudio) selectCamera;
|
||||||
|
final bool isHomeView;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<CameraPreviewControllerView> createState() =>
|
State<CameraPreviewControllerView> createState() =>
|
||||||
|
|
@ -57,6 +106,7 @@ class _CameraPreviewControllerView extends State<CameraPreviewControllerView> {
|
||||||
return CameraPreviewView(
|
return CameraPreviewView(
|
||||||
sendTo: widget.sendTo,
|
sendTo: widget.sendTo,
|
||||||
selectCamera: widget.selectCamera,
|
selectCamera: widget.selectCamera,
|
||||||
|
isHomeView: widget.isHomeView,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return PermissionHandlerView(onSuccess: () {
|
return PermissionHandlerView(onSuccess: () {
|
||||||
|
|
@ -72,12 +122,13 @@ class _CameraPreviewControllerView extends State<CameraPreviewControllerView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
class CameraPreviewView extends StatefulWidget {
|
class CameraPreviewView extends StatefulWidget {
|
||||||
const CameraPreviewView({
|
const CameraPreviewView(
|
||||||
super.key,
|
{super.key,
|
||||||
this.sendTo,
|
this.sendTo,
|
||||||
required this.selectCamera,
|
required this.selectCamera,
|
||||||
});
|
required this.isHomeView});
|
||||||
final Contact? sendTo;
|
final Contact? sendTo;
|
||||||
|
final bool isHomeView;
|
||||||
final Function(int sCameraId, bool init, bool enableAudio) selectCamera;
|
final Function(int sCameraId, bool init, bool enableAudio) selectCamera;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -109,6 +160,18 @@ 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;
|
||||||
|
|
||||||
void initAsync() async {
|
void initAsync() async {
|
||||||
final user = await getUser();
|
final user = await getUser();
|
||||||
if (user == null) return;
|
if (user == null) return;
|
||||||
|
|
@ -139,13 +202,13 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateScaleFactor(double newScale) async {
|
Future<void> updateScaleFactor(double newScale) async {
|
||||||
if (HomeViewState.selectedCameraDetails.scaleFactor == newScale ||
|
if (selectedCameraDetails.scaleFactor == newScale ||
|
||||||
HomeViewState.cameraController == null) return;
|
cameraController == null) return;
|
||||||
await HomeViewState.cameraController?.setZoomLevel(newScale.clamp(
|
await cameraController?.setZoomLevel(newScale.clamp(
|
||||||
HomeViewState.selectedCameraDetails.minAvailableZoom,
|
selectedCameraDetails.minAvailableZoom,
|
||||||
HomeViewState.selectedCameraDetails.maxAvailableZoom));
|
selectedCameraDetails.maxAvailableZoom));
|
||||||
setState(() {
|
setState(() {
|
||||||
HomeViewState.selectedCameraDetails.scaleFactor = newScale;
|
selectedCameraDetails.scaleFactor = newScale;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,25 +240,23 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
setState(() {
|
setState(() {
|
||||||
sharePreviewIsShown = true;
|
sharePreviewIsShown = true;
|
||||||
});
|
});
|
||||||
if (HomeViewState.selectedCameraDetails.isFlashOn) {
|
if (selectedCameraDetails.isFlashOn) {
|
||||||
if (isFront) {
|
if (isFront) {
|
||||||
setState(() {
|
setState(() {
|
||||||
showSelfieFlash = true;
|
showSelfieFlash = true;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
HomeViewState.cameraController?.setFlashMode(FlashMode.torch);
|
cameraController?.setFlashMode(FlashMode.torch);
|
||||||
}
|
}
|
||||||
await Future.delayed(Duration(milliseconds: 1000));
|
await Future.delayed(Duration(milliseconds: 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
await HomeViewState.cameraController?.pausePreview();
|
await cameraController?.pausePreview();
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
|
|
||||||
HomeViewState.cameraController?.setFlashMode(
|
cameraController?.setFlashMode(
|
||||||
HomeViewState.selectedCameraDetails.isFlashOn
|
selectedCameraDetails.isFlashOn ? FlashMode.always : FlashMode.off);
|
||||||
? FlashMode.always
|
imageBytes = screenshotController.capture(
|
||||||
: FlashMode.off);
|
|
||||||
imageBytes = HomeViewState.screenshotController.capture(
|
|
||||||
pixelRatio:
|
pixelRatio:
|
||||||
(useHighQuality) ? MediaQuery.of(context).devicePixelRatio : 1);
|
(useHighQuality) ? MediaQuery.of(context).devicePixelRatio : 1);
|
||||||
|
|
||||||
|
|
@ -235,8 +296,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
widget.selectCamera(
|
widget.selectCamera(selectedCameraDetails.cameraId, false, false);
|
||||||
HomeViewState.selectedCameraDetails.cameraId, false, false);
|
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
sharePreviewIsShown = false;
|
sharePreviewIsShown = false;
|
||||||
|
|
@ -247,22 +307,20 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get isFront =>
|
bool get isFront =>
|
||||||
HomeViewState.cameraController?.description.lensDirection ==
|
cameraController?.description.lensDirection == CameraLensDirection.front;
|
||||||
CameraLensDirection.front;
|
|
||||||
|
|
||||||
Future onPanUpdate(details) async {
|
Future onPanUpdate(details) async {
|
||||||
if (isFront) {
|
if (isFront) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (HomeViewState.cameraController == null) return;
|
if (cameraController == null) return;
|
||||||
if (!HomeViewState.cameraController!.value.isInitialized) return;
|
if (!cameraController!.value.isInitialized) return;
|
||||||
|
|
||||||
HomeViewState.selectedCameraDetails.scaleFactor =
|
selectedCameraDetails.scaleFactor =
|
||||||
(baseScaleFactor + (basePanY - details.localPosition.dy) / 30)
|
(baseScaleFactor + (basePanY - details.localPosition.dy) / 30)
|
||||||
.clamp(1, HomeViewState.selectedCameraDetails.maxAvailableZoom);
|
.clamp(1, selectedCameraDetails.maxAvailableZoom);
|
||||||
|
|
||||||
await HomeViewState.cameraController!
|
await cameraController!.setZoomLevel(selectedCameraDetails.scaleFactor);
|
||||||
.setZoomLevel(HomeViewState.selectedCameraDetails.scaleFactor);
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
@ -289,11 +347,11 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future startVideoRecording() async {
|
Future startVideoRecording() async {
|
||||||
if (HomeViewState.cameraController != null &&
|
if (cameraController != null && cameraController!.value.isRecordingVideo)
|
||||||
HomeViewState.cameraController!.value.isRecordingVideo) return;
|
return;
|
||||||
if (hasAudioPermission && videoWithAudio) {
|
if (hasAudioPermission && videoWithAudio) {
|
||||||
await widget.selectCamera(
|
await widget.selectCamera(
|
||||||
HomeViewState.selectedCameraDetails.cameraId,
|
selectedCameraDetails.cameraId,
|
||||||
false,
|
false,
|
||||||
await Permission.microphone.isGranted && videoWithAudio,
|
await Permission.microphone.isGranted && videoWithAudio,
|
||||||
);
|
);
|
||||||
|
|
@ -304,7 +362,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await HomeViewState.cameraController?.startVideoRecording();
|
await cameraController?.startVideoRecording();
|
||||||
videoRecordingTimer = Timer.periodic(Duration(milliseconds: 15), (timer) {
|
videoRecordingTimer = Timer.periodic(Duration(milliseconds: 15), (timer) {
|
||||||
setState(() {
|
setState(() {
|
||||||
currentTime = DateTime.now();
|
currentTime = DateTime.now();
|
||||||
|
|
@ -335,8 +393,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
videoRecordingTimer?.cancel();
|
videoRecordingTimer?.cancel();
|
||||||
videoRecordingTimer = null;
|
videoRecordingTimer = null;
|
||||||
}
|
}
|
||||||
if (HomeViewState.cameraController == null ||
|
if (cameraController == null || !cameraController!.value.isRecordingVideo) {
|
||||||
!HomeViewState.cameraController!.value.isRecordingVideo) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -347,8 +404,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
sharePreviewIsShown = true;
|
sharePreviewIsShown = true;
|
||||||
});
|
});
|
||||||
File? videoPathFile;
|
File? videoPathFile;
|
||||||
XFile? videoPath =
|
XFile? videoPath = await cameraController?.stopVideoRecording();
|
||||||
await HomeViewState.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
|
||||||
|
|
@ -358,7 +414,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
videoPathFile = File(videoPath.path);
|
videoPathFile = File(videoPath.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await HomeViewState.cameraController?.pausePreview();
|
await cameraController?.pausePreview();
|
||||||
if (await pushMediaEditor(null, videoPathFile)) {
|
if (await pushMediaEditor(null, videoPathFile)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -386,8 +442,8 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (HomeViewState.selectedCameraDetails.cameraId >= gCameras.length ||
|
if (selectedCameraDetails.cameraId >= gCameras.length ||
|
||||||
HomeViewState.cameraController == null) {
|
cameraController == null) {
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
return MediaViewSizing(
|
return MediaViewSizing(
|
||||||
|
|
@ -398,14 +454,14 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
}
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
basePanY = details.localPosition.dy;
|
basePanY = details.localPosition.dy;
|
||||||
baseScaleFactor = HomeViewState.selectedCameraDetails.scaleFactor;
|
baseScaleFactor = selectedCameraDetails.scaleFactor;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onLongPressMoveUpdate: onPanUpdate,
|
onLongPressMoveUpdate: onPanUpdate,
|
||||||
onLongPressStart: (details) {
|
onLongPressStart: (details) {
|
||||||
setState(() {
|
setState(() {
|
||||||
basePanY = details.localPosition.dy;
|
basePanY = details.localPosition.dy;
|
||||||
baseScaleFactor = HomeViewState.selectedCameraDetails.scaleFactor;
|
baseScaleFactor = selectedCameraDetails.scaleFactor;
|
||||||
});
|
});
|
||||||
// Get the position of the pointer
|
// Get the position of the pointer
|
||||||
RenderBox renderBox =
|
RenderBox renderBox =
|
||||||
|
|
@ -431,7 +487,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
children: [
|
children: [
|
||||||
// if (!galleryLoadedImageIsShown)
|
// if (!galleryLoadedImageIsShown)
|
||||||
// CameraPreviewWidget(
|
// CameraPreviewWidget(
|
||||||
// controller: HomeViewState.cameraController,
|
// controller: cameraController,
|
||||||
// screenshotController: screenshotController,
|
// screenshotController: screenshotController,
|
||||||
// ),
|
// ),
|
||||||
if (galleryLoadedImageIsShown)
|
if (galleryLoadedImageIsShown)
|
||||||
|
|
@ -466,32 +522,26 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
tooltipText: context.lang.switchFrontAndBackCamera,
|
tooltipText: context.lang.switchFrontAndBackCamera,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
widget.selectCamera(
|
widget.selectCamera(
|
||||||
(HomeViewState.selectedCameraDetails.cameraId +
|
(selectedCameraDetails.cameraId + 1) % 2,
|
||||||
1) %
|
|
||||||
2,
|
|
||||||
false,
|
false,
|
||||||
false);
|
false);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ActionButton(
|
ActionButton(
|
||||||
HomeViewState.selectedCameraDetails.isFlashOn
|
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: HomeViewState.selectedCameraDetails.isFlashOn
|
color: selectedCameraDetails.isFlashOn
|
||||||
? Colors.white
|
? Colors.white
|
||||||
: Colors.white.withAlpha(160),
|
: Colors.white.withAlpha(160),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (HomeViewState.selectedCameraDetails.isFlashOn) {
|
if (selectedCameraDetails.isFlashOn) {
|
||||||
HomeViewState.cameraController
|
cameraController?.setFlashMode(FlashMode.off);
|
||||||
?.setFlashMode(FlashMode.off);
|
selectedCameraDetails.isFlashOn = false;
|
||||||
HomeViewState.selectedCameraDetails.isFlashOn =
|
|
||||||
false;
|
|
||||||
} else {
|
} else {
|
||||||
HomeViewState.cameraController
|
cameraController?.setFlashMode(FlashMode.always);
|
||||||
?.setFlashMode(FlashMode.always);
|
selectedCameraDetails.isFlashOn = true;
|
||||||
HomeViewState.selectedCameraDetails.isFlashOn =
|
|
||||||
true;
|
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
|
|
@ -550,18 +600,17 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
if (HomeViewState.cameraController!.value.isInitialized &&
|
if (cameraController!.value.isInitialized &&
|
||||||
HomeViewState.selectedCameraDetails.isZoomAble &&
|
selectedCameraDetails.isZoomAble &&
|
||||||
!isFront &&
|
!isFront &&
|
||||||
!isVideoRecording)
|
!isVideoRecording)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 120,
|
width: 120,
|
||||||
child: CameraZoomButtons(
|
child: CameraZoomButtons(
|
||||||
key: widget.key,
|
key: widget.key,
|
||||||
scaleFactor:
|
scaleFactor: selectedCameraDetails.scaleFactor,
|
||||||
HomeViewState.selectedCameraDetails.scaleFactor,
|
|
||||||
updateScaleFactor: updateScaleFactor,
|
updateScaleFactor: updateScaleFactor,
|
||||||
controller: HomeViewState.cameraController!,
|
controller: cameraController!,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 30),
|
const SizedBox(height: 30),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
|
import 'package:camera/camera.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:screenshot/screenshot.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
|
import 'package:twonly/src/views/camera/camera_preview_components/camera_preview.dart';
|
||||||
import 'package:twonly/src/views/camera/camera_preview_controller_view.dart';
|
import 'package:twonly/src/views/camera/camera_preview_controller_view.dart';
|
||||||
|
|
||||||
class CameraSendToView extends StatefulWidget {
|
class CameraSendToView extends StatefulWidget {
|
||||||
|
|
@ -10,11 +13,46 @@ class CameraSendToView extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class CameraSendToViewState extends State<CameraSendToView> {
|
class CameraSendToViewState extends State<CameraSendToView> {
|
||||||
|
static CameraController? cameraController;
|
||||||
|
static ScreenshotController screenshotController = ScreenshotController();
|
||||||
|
static SelectedCameraDetails selectedCameraDetails = SelectedCameraDetails();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
selectCamera(0, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future selectCamera(int sCameraId, bool init, bool enableAudio) async {
|
||||||
|
final opts = await initializeCameraController(
|
||||||
|
selectedCameraDetails, sCameraId, init, enableAudio);
|
||||||
|
if (opts != null) {
|
||||||
|
selectedCameraDetails = opts.$1;
|
||||||
|
cameraController = opts.$2;
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future toggleSelectedCamera() async {
|
||||||
|
selectCamera((selectedCameraDetails.cameraId + 1) % 2, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold();
|
return Scaffold(
|
||||||
// return Scaffold(
|
body: GestureDetector(
|
||||||
// body: CameraPreviewControllerView(sendTo: widget.sendTo),
|
onDoubleTap: toggleSelectedCamera,
|
||||||
// );
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
SendToCameraPreview(),
|
||||||
|
CameraPreviewControllerView(
|
||||||
|
selectCamera: selectCamera,
|
||||||
|
sendTo: widget.sendTo,
|
||||||
|
isHomeView: false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,9 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:camera/camera.dart';
|
import 'package:camera/camera.dart';
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:logging/logging.dart';
|
|
||||||
import 'package:pie_menu/pie_menu.dart';
|
import 'package:pie_menu/pie_menu.dart';
|
||||||
import 'package:screenshot/screenshot.dart';
|
import 'package:screenshot/screenshot.dart';
|
||||||
import 'package:twonly/globals.dart';
|
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/views/camera/camera_preview_components/camera_preview.dart';
|
import 'package:twonly/src/views/camera/camera_preview_components/camera_preview.dart';
|
||||||
import 'package:twonly/src/views/components/user_context_menu.dart';
|
import 'package:twonly/src/views/components/user_context_menu.dart';
|
||||||
|
|
@ -58,6 +54,7 @@ class HomeViewState extends State<HomeView> {
|
||||||
double offsetFromOne = 0.0;
|
double offsetFromOne = 0.0;
|
||||||
|
|
||||||
Timer? disableCameraTimer;
|
Timer? disableCameraTimer;
|
||||||
|
bool initCameraStarted = true;
|
||||||
|
|
||||||
static CameraController? cameraController;
|
static CameraController? cameraController;
|
||||||
static ScreenshotController screenshotController = ScreenshotController();
|
static ScreenshotController screenshotController = ScreenshotController();
|
||||||
|
|
@ -71,7 +68,8 @@ class HomeViewState extends State<HomeView> {
|
||||||
offsetRatio = offsetFromOne.abs();
|
offsetRatio = offsetFromOne.abs();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (cameraController == null) {
|
if (cameraController == null && !initCameraStarted) {
|
||||||
|
initCameraStarted = true;
|
||||||
selectCamera(selectedCameraDetails.cameraId, false, false);
|
selectCamera(selectedCameraDetails.cameraId, false, false);
|
||||||
}
|
}
|
||||||
if (offsetRatio == 1) {
|
if (offsetRatio == 1) {
|
||||||
|
|
@ -110,46 +108,13 @@ class HomeViewState extends State<HomeView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future selectCamera(int sCameraId, bool init, bool enableAudio) async {
|
Future selectCamera(int sCameraId, bool init, bool enableAudio) async {
|
||||||
if (sCameraId >= gCameras.length) return;
|
final opts = await initializeCameraController(
|
||||||
if (init) {
|
selectedCameraDetails, sCameraId, init, enableAudio);
|
||||||
for (; sCameraId < gCameras.length; sCameraId++) {
|
if (opts != null) {
|
||||||
if (gCameras[sCameraId].lensDirection == CameraLensDirection.back) {
|
selectedCameraDetails = opts.$1;
|
||||||
break;
|
cameraController = opts.$2;
|
||||||
}
|
initCameraStarted = false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
selectedCameraDetails.isZoomAble = false;
|
|
||||||
if (selectedCameraDetails.cameraId != sCameraId) {
|
|
||||||
// switch between front and back
|
|
||||||
selectedCameraDetails.scaleFactor = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
cameraController = CameraController(
|
|
||||||
gCameras[sCameraId],
|
|
||||||
ResolutionPreset.high,
|
|
||||||
enableAudio: enableAudio,
|
|
||||||
);
|
|
||||||
|
|
||||||
await cameraController?.initialize().then((_) async {
|
|
||||||
await cameraController?.setZoomLevel(selectedCameraDetails.scaleFactor);
|
|
||||||
await cameraController
|
|
||||||
?.lockCaptureOrientation(DeviceOrientation.portraitUp);
|
|
||||||
cameraController?.setFlashMode(
|
|
||||||
selectedCameraDetails.isFlashOn ? FlashMode.always : FlashMode.off);
|
|
||||||
await cameraController?.getMaxZoomLevel().then(
|
|
||||||
(double value) => selectedCameraDetails.maxAvailableZoom = value);
|
|
||||||
await cameraController?.getMinZoomLevel().then(
|
|
||||||
(double value) => selectedCameraDetails.minAvailableZoom = value);
|
|
||||||
selectedCameraDetails.isZoomAble =
|
|
||||||
selectedCameraDetails.maxAvailableZoom !=
|
|
||||||
selectedCameraDetails.minAvailableZoom;
|
|
||||||
setState(() {
|
|
||||||
selectedCameraDetails.cameraLoaded = true;
|
|
||||||
selectedCameraDetails.cameraId = sCameraId;
|
|
||||||
});
|
|
||||||
}).catchError((Object e) {
|
|
||||||
Logger("home_view.dart").shout("$e");
|
|
||||||
});
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,7 +142,7 @@ class HomeViewState extends State<HomeView> {
|
||||||
onDoubleTap: offsetRatio == 0 ? toggleSelectedCamera : null,
|
onDoubleTap: offsetRatio == 0 ? toggleSelectedCamera : null,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
CameraPreviewWidget(),
|
HomeViewCameraPreview(),
|
||||||
Shade(
|
Shade(
|
||||||
opacity: offsetRatio,
|
opacity: offsetRatio,
|
||||||
),
|
),
|
||||||
|
|
@ -210,6 +175,7 @@ class HomeViewState extends State<HomeView> {
|
||||||
opacity: (1 - (offsetRatio * 4) % 1),
|
opacity: (1 - (offsetRatio * 4) % 1),
|
||||||
child: CameraPreviewControllerView(
|
child: CameraPreviewControllerView(
|
||||||
selectCamera: selectCamera,
|
selectCamera: selectCamera,
|
||||||
|
isHomeView: true,
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue