Skip to content

Commit

Permalink
🔖 3.5.0 (#117)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexV525 authored Aug 13, 2022
1 parent 98392a0 commit 0e5a391
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 37 deletions.
17 changes: 4 additions & 13 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,7 @@ that can be found in the LICENSE file. -->

# Changelog

## 3.5.0-dev.3

### Improvements

- Prevent switching cameras when taking picture or recording video. (#120)

## 3.5.0-dev.2

### Improvements

- Re-export `CameraPicker`'s constructor. (#116)

## 3.5.0-dev.1
## 3.5.0

### New features

Expand All @@ -25,6 +13,9 @@ that can be found in the LICENSE file. -->
### Improvements

- Expose multiple internal widgets. (#113)
- Re-export `CameraPicker`'s constructor. (#116)
- Avoid duplicate entity saving. (#117)
- Prevent switching cameras when taking picture or recording video. (#120)

## 3.4.0

Expand Down
2 changes: 2 additions & 0 deletions lib/src/internals/methods.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ void handleErrorWithHandler(
}
throw e;
}

T? ambiguate<T>(T value) => value;
29 changes: 15 additions & 14 deletions lib/src/states/camera_picker_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import 'dart:async';
import 'dart:io';
import 'dart:math' as math;

import 'package:bindings_compatible/bindings_compatible.dart';
import 'package:camera/camera.dart';
import 'package:camera_platform_interface/camera_platform_interface.dart';
import 'package:flutter/gestures.dart';
Expand Down Expand Up @@ -49,7 +48,9 @@ class CameraPickerState extends State<CameraPicker>
/// 在开始录像前,最后一次在拍照按钮按下的位置
Offset? lastShootingButtonPressedPosition;

final ValueNotifier<bool> isExposureModeDisplays = ValueNotifier<bool>(false);
/// Whether the focus point is displaying.
/// 是否正在展示当前的聚焦点
final ValueNotifier<bool> isFocusPointDisplays = ValueNotifier<bool>(false);

/// The controller for the current camera.
/// 当前相机实例的控制器
Expand All @@ -58,7 +59,7 @@ class CameraPickerState extends State<CameraPicker>

/// Available cameras.
/// 可用的相机实例
late List<CameraDescription> cameras;
late final List<CameraDescription> cameras;

/// Current exposure offset.
/// 当前曝光值
Expand Down Expand Up @@ -162,7 +163,7 @@ class CameraPickerState extends State<CameraPicker>
@override
void initState() {
super.initState();
useWidgetsBinding().addObserver(this);
ambiguate(WidgetsBinding.instance)?.addObserver(this);

// TODO(Alex): Currently hide status bar will cause the viewport shaking on Android.
/// Hide system status bar automatically when the platform is not Android.
Expand All @@ -179,11 +180,11 @@ class CameraPickerState extends State<CameraPicker>
if (!Platform.isAndroid) {
SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
}
useWidgetsBinding().removeObserver(this);
ambiguate(WidgetsBinding.instance)?.removeObserver(this);
innerController?.dispose();
currentExposureOffset.dispose();
lastExposurePoint.dispose();
isExposureModeDisplays.dispose();
isFocusPointDisplays.dispose();
exposurePointDisplayTimer?.cancel();
exposureModeDisplayTimer?.cancel();
recordDetectTimer?.cancel();
Expand Down Expand Up @@ -255,7 +256,7 @@ class CameraPickerState extends State<CameraPicker>
});
// **IMPORTANT**: Push methods into a post frame callback, which ensures the
// controller has already unbind from widgets.
useWidgetsBinding().addPostFrameCallback((_) async {
ambiguate(WidgetsBinding.instance)?.addPostFrameCallback((_) async {
// When the [cameraDescription] is null, which means this is the first
// time initializing cameras, so available cameras should be fetched.
if (cameraDescription == null) {
Expand All @@ -264,7 +265,7 @@ class CameraPickerState extends State<CameraPicker>

// After cameras fetched, judge again with the list is empty or not to
// ensure there is at least an available camera for use.
if (cameraDescription == null && (cameras.isEmpty)) {
if (cameraDescription == null && cameras.isEmpty) {
handleErrorWithHandler(
CameraException(
'No CameraDescription found.',
Expand Down Expand Up @@ -440,7 +441,7 @@ class CameraPickerState extends State<CameraPicker>
void restartDisplayModeDisplayTimer() {
exposureModeDisplayTimer?.cancel();
exposureModeDisplayTimer = Timer(const Duration(seconds: 2), () {
isExposureModeDisplays.value = false;
isFocusPointDisplays.value = false;
});
}

Expand Down Expand Up @@ -474,7 +475,7 @@ class CameraPickerState extends State<CameraPicker>
Offset position,
BoxConstraints constraints,
) async {
isExposureModeDisplays.value = false;
isFocusPointDisplays.value = false;
// Ignore point update when the new point is less than 8% and higher than
// 92% of the screen's height.
if (position.dy < constraints.maxHeight / 12 ||
Expand Down Expand Up @@ -535,8 +536,8 @@ class CameraPickerState extends State<CameraPicker>
} catch (e, s) {
handleErrorWithHandler(e, pickerConfig.onError, s: s);
}
if (!isExposureModeDisplays.value) {
isExposureModeDisplays.value = true;
if (!isFocusPointDisplays.value) {
isFocusPointDisplays.value = true;
}
restartDisplayModeDisplayTimer();
restartExposurePointDisplayTimer();
Expand Down Expand Up @@ -1008,7 +1009,7 @@ class CameraPickerState extends State<CameraPicker>
final bool isLocked = mode == ExposureMode.locked;
final Color? color = isLocked ? _lockedColor : theme.iconTheme.color;
final Widget lineWidget = ValueListenableBuilder<bool>(
valueListenable: isExposureModeDisplays,
valueListenable: isFocusPointDisplays,
builder: (_, bool value, Widget? child) => AnimatedOpacity(
duration: _kDuration,
opacity: value ? 1 : 0,
Expand Down Expand Up @@ -1077,7 +1078,7 @@ class CameraPickerState extends State<CameraPicker>
return Column(
children: <Widget>[
ValueListenableBuilder<bool>(
valueListenable: isExposureModeDisplays,
valueListenable: isFocusPointDisplays,
builder: (_, bool value, Widget? child) => AnimatedOpacity(
duration: _kDuration,
opacity: value ? 1 : 0,
Expand Down
24 changes: 19 additions & 5 deletions lib/src/states/camera_picker_viewer_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ class CameraPickerViewerState extends State<CameraPickerViewer> {
/// 初始化视频控制器时是否发生错误
bool hasErrorWhenInitializing = false;

/// Whether the saving process is ongoing.
bool isSavingEntity = false;

CameraErrorHandler? get onError => widget.pickerConfig.onError;

@override
Expand Down Expand Up @@ -121,13 +124,23 @@ class CameraPickerViewerState extends State<CameraPickerViewer> {
/// While the entity might returned null, there's no side effects if popping `null`
/// because the parent picker will ignore it.
Future<void> createAssetEntityAndPop() async {
if (isSavingEntity) {
return;
}
isSavingEntity = true;
final CameraPickerViewType viewType = widget.viewType;
if (widget.pickerConfig.onEntitySaving != null) {
await widget.pickerConfig.onEntitySaving!(
context,
widget.viewType,
File(widget.previewXFile.path),
);
try {
await widget.pickerConfig.onEntitySaving!(
context,
widget.viewType,
File(widget.previewXFile.path),
);
} catch (e, s) {
handleErrorWithHandler(e, widget.pickerConfig.onError, s: s);
} finally {
isSavingEntity = false;
}
return;
}
AssetEntity? entity;
Expand Down Expand Up @@ -165,6 +178,7 @@ class CameraPickerViewerState extends State<CameraPickerViewer> {
realDebugPrint('Saving entity failed: $e');
handleErrorWithHandler(e, widget.pickerConfig.onError, s: s);
} finally {
isSavingEntity = false;
if (mounted) {
Navigator.of(context).pop(entity);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/src/widgets/camera_progress_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

import 'dart:math' as math;

import 'package:bindings_compatible/bindings_compatible.dart';
import 'package:flutter/material.dart';

import '../constants/styles.dart';
import '../internals/methods.dart';

class CameraProgressButton extends StatefulWidget {
const CameraProgressButton({
Expand Down Expand Up @@ -41,7 +41,7 @@ class _CircleProgressState extends State<CameraProgressButton>
@override
void initState() {
super.initState();
useWidgetsBinding().addPostFrameCallback((Duration _) {
ambiguate(WidgetsBinding.instance)?.addPostFrameCallback((_) {
progressController.forward();
});
}
Expand Down
5 changes: 2 additions & 3 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: wechat_camera_picker
description: A camera picker which is an extension to wechat_assets_picker, but can be run separately.
version: 3.5.0-dev.3
version: 3.5.0
homepage: https://github.com/fluttercandies/flutter_wechat_camera_picker

environment:
Expand All @@ -11,9 +11,8 @@ dependencies:
flutter:
sdk: flutter

bindings_compatible: ^1.0.1
camera: ^0.9.6
camera_platform_interface: ^2.1.5
path: ^1.8.0
photo_manager: ^2.1.0+2
photo_manager: ^2.2.0
video_player: ^2.3.2

0 comments on commit 0e5a391

Please sign in to comment.