You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
6.1 KiB
163 lines
6.1 KiB
1 year ago
|
// SPDX-FileCopyrightText: Copyright 2023 Open Mobile Platform LLC <community@omp.ru>
|
||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||
|
import 'dart:io';
|
||
|
|
||
|
import 'package:camera/camera.dart';
|
||
|
import 'package:flutter/material.dart';
|
||
|
import 'package:flutter_example_packages/base/di/app_di.dart';
|
||
|
import 'package:flutter_example_packages/base/package/package.dart';
|
||
|
import 'package:flutter_example_packages/packages/camera/extension/export.dart';
|
||
|
import 'package:flutter_example_packages/packages/camera/widgets/camera_body.dart';
|
||
|
import 'package:flutter_example_packages/packages/camera/widgets/camera_control_panel.dart';
|
||
|
import 'package:flutter_example_packages/packages/camera/widgets/cameras_loading.dart';
|
||
|
import 'package:flutter_example_packages/packages/camera/widgets/cameras_select.dart';
|
||
|
import 'package:flutter_example_packages/theme/colors.dart';
|
||
|
import 'package:flutter_example_packages/widgets/base/export.dart';
|
||
|
import 'package:flutter_example_packages/widgets/layouts/block_layout.dart';
|
||
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||
|
|
||
|
import 'model.dart';
|
||
|
import 'package.dart';
|
||
|
|
||
|
class CameraPage extends AppStatefulWidget {
|
||
|
CameraPage({
|
||
|
super.key,
|
||
|
});
|
||
|
|
||
|
final Package package = packageCamera;
|
||
|
|
||
|
@override
|
||
|
State<CameraPage> createState() => _CameraPageState();
|
||
|
}
|
||
|
|
||
|
class _CameraPageState extends AppState<CameraPage> {
|
||
|
CameraController? _cameraController;
|
||
|
File? _photo;
|
||
|
File? _video;
|
||
|
bool _loading = false;
|
||
|
|
||
|
@override
|
||
|
Widget buildWide(
|
||
|
BuildContext context,
|
||
|
MediaQueryData media,
|
||
|
AppLocalizations l10n,
|
||
|
) {
|
||
|
return BlockLayout<CameraModel>(
|
||
|
model: getIt<CameraModel>(),
|
||
|
title: widget.package.key,
|
||
|
builder: (context, child, model) {
|
||
|
return Padding(
|
||
|
padding: const EdgeInsets.all(20),
|
||
|
child: CamerasLoading(
|
||
|
package: widget.package,
|
||
|
builder: (context, cameras) {
|
||
|
return Column(
|
||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||
|
children: [
|
||
|
Flexible(
|
||
|
flex: 1,
|
||
|
child: Column(
|
||
|
children: [
|
||
|
Flexible(
|
||
|
flex: 0,
|
||
|
child: CamerasSelect(
|
||
|
disable: _loading,
|
||
|
cameras: cameras,
|
||
|
onChange: (controller) => setState(() {
|
||
|
_photo = null;
|
||
|
_cameraController = controller;
|
||
|
}),
|
||
|
),
|
||
|
),
|
||
|
const SizedBox(height: 5),
|
||
|
Flexible(
|
||
|
flex: 1,
|
||
|
child: CameraBody(
|
||
|
loading: _loading,
|
||
|
controller: _cameraController,
|
||
|
photo: _photo,
|
||
|
),
|
||
|
),
|
||
|
CameraControlPanel(
|
||
|
disable: _loading,
|
||
|
controller: _cameraController,
|
||
|
photo: _photo,
|
||
|
// Start record video
|
||
|
onRecordingStart: () => _cameraController
|
||
|
?.startVideoRecording()
|
||
|
.then((picture) {
|
||
|
if (mounted) {
|
||
|
setState(() {});
|
||
|
}
|
||
|
}),
|
||
|
// Pause record video if record already start
|
||
|
onRecordingPause: () => _cameraController
|
||
|
?.pauseVideoRecording()
|
||
|
.then((value) {
|
||
|
if (mounted) {
|
||
|
setState(() {});
|
||
|
}
|
||
|
}),
|
||
|
// Resume record video if record already start and will pause
|
||
|
onRecordingResume: () => _cameraController
|
||
|
?.resumeVideoRecording()
|
||
|
.then((value) {
|
||
|
if (mounted) {
|
||
|
setState(() {});
|
||
|
}
|
||
|
}),
|
||
|
// Clear photo
|
||
|
onClearPhoto: () {
|
||
|
if (mounted) {
|
||
|
setState(() {
|
||
|
_photo = null;
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
// Stop record video and save to file (custom extension)
|
||
|
onRecordingStop: () => _cameraController
|
||
|
?.takeVideoFileAndStopRecording()
|
||
|
.then((video) {
|
||
|
if (mounted) {
|
||
|
showMessage(video);
|
||
|
setState(() {
|
||
|
_video = video;
|
||
|
});
|
||
|
}
|
||
|
}),
|
||
|
// Take photo and save to file (custom extension)
|
||
|
onTakePhoto: () => setState(() {
|
||
|
_loading = true;
|
||
|
_cameraController?.takeImageFile().then((photo) {
|
||
|
if (mounted) {
|
||
|
showMessage(photo);
|
||
|
setState(() {
|
||
|
_loading = false;
|
||
|
_photo = photo;
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
}),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
);
|
||
|
},
|
||
|
),
|
||
|
);
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
|
||
|
void showMessage(File? file) {
|
||
|
if (file != null) {
|
||
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||
|
content: Text("File save to: ${file.path}"),
|
||
|
backgroundColor: AppColors.secondary,
|
||
|
));
|
||
|
}
|
||
|
}
|
||
|
}
|